home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / C and C++ / Gnuplot 3.5 for Macintosh / SOURCES 3.5 / setshow_2.c < prev    next >
Text File  |  1993-11-12  |  79KB  |  3,202 lines

  1. static char *RCSid = "$Id: setshow.c%v 3.50.1.11 1993/08/10 03:55:03 woo Exp $";
  2.  
  3.  
  4. /* GNUPLOT - setshow.c */
  5. /*
  6.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  7.  *
  8.  * Permission to use, copy, and distribute this software and its
  9.  * documentation for any purpose with or without fee is hereby granted, 
  10.  * provided that the above copyright notice appear in all copies and 
  11.  * that both that copyright notice and this permission notice appear 
  12.  * in supporting documentation.
  13.  *
  14.  * Permission to modify the software is granted, but not the right to
  15.  * distribute the modified code.  Modifications are to be distributed 
  16.  * as patches to released version.
  17.  *  
  18.  * This software is provided "as is" without express or implied warranty.
  19.  * 
  20.  *
  21.  * AUTHORS
  22.  * 
  23.  *   Original Software:
  24.  *     Thomas Williams,  Colin Kelley.
  25.  * 
  26.  *   Gnuplot 2.0 additions:
  27.  *       Russell Lang, Dave Kotz, John Campbell.
  28.  *
  29.  *   Gnuplot 3.0 additions:
  30.  *       Gershon Elber and many others.
  31.  *
  32.  * 19 September 1992  Lawrence Crowl  (crowl@cs.orst.edu)
  33.  * Added user-specified bases for log scaling.
  34.  * 
  35.  * There is a mailing list for gnuplot users. Note, however, that the
  36.  * newsgroup 
  37.  *    comp.graphics.gnuplot 
  38.  * is identical to the mailing list (they
  39.  * both carry the same set of messages). We prefer that you read the
  40.  * messages through that newsgroup, to subscribing to the mailing list.
  41.  * (If you can read that newsgroup, and are already on the mailing list,
  42.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  43.  * removed from the mailing list.)
  44.  *
  45.  * The address for mailing to list members is
  46.  *       info-gnuplot@dartmouth.edu
  47.  * and for mailing administrative requests is 
  48.  *       info-gnuplot-request@dartmouth.edu
  49.  * The mailing list for bug reports is 
  50.  *       bug-gnuplot@dartmouth.edu
  51.  * The list of those interested in beta-test versions is
  52.  *       info-gnuplot-beta@dartmouth.edu
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <math.h>
  57. #include "plot.h"
  58. #ifdef THINK_C
  59. #include "tout_protos.h"
  60. #endif
  61. #include "setshow.h"
  62.  
  63. #define DEF_FORMAT   "%g"    /* default format for tic mark labels */
  64. #define SIGNIF (0.01)        /* less than one hundredth of a tic mark */
  65.  
  66. #ifdef THINK_C
  67. #define THINK_C_2
  68. #endif
  69.  
  70. #ifdef THINK_C_1
  71. /*
  72.  * global variables to hold status of 'set' options
  73.  *
  74.  */
  75. TBOOLEAN        autoscale_r    = TRUE;
  76. TBOOLEAN        autoscale_t    = TRUE;
  77. TBOOLEAN        autoscale_u    = TRUE;
  78. TBOOLEAN        autoscale_v    = TRUE;
  79. TBOOLEAN        autoscale_x    = TRUE;
  80. TBOOLEAN        autoscale_y    = TRUE;
  81. TBOOLEAN        autoscale_z    = TRUE;
  82. TBOOLEAN        autoscale_lt    = TRUE;
  83. TBOOLEAN        autoscale_lu    = TRUE;
  84. TBOOLEAN        autoscale_lv    = TRUE;
  85. TBOOLEAN        autoscale_lx    = TRUE;
  86. TBOOLEAN        autoscale_ly    = TRUE;
  87. TBOOLEAN        autoscale_lz    = TRUE;
  88. double            boxwidth    = -1.0; /* box width (automatic) */
  89. TBOOLEAN         clip_points    = FALSE;
  90. TBOOLEAN         clip_lines1    = TRUE;
  91. TBOOLEAN         clip_lines2    = FALSE;
  92. TBOOLEAN        draw_border    = TRUE;
  93. TBOOLEAN        draw_surface    = TRUE;
  94. TBOOLEAN        timedate    = FALSE;
  95. char            dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1] = { "x", "y" };
  96. char            xformat[MAX_ID_LEN+1] = DEF_FORMAT;
  97. char            yformat[MAX_ID_LEN+1] = DEF_FORMAT;
  98. char            zformat[MAX_ID_LEN+1] = DEF_FORMAT;
  99. enum PLOT_STYLE        data_style    = POINTSTYLE;
  100. enum PLOT_STYLE        func_style    = LINES;
  101. TBOOLEAN        grid        = FALSE;
  102. int            key        = -1;    /* default position */
  103. double            key_x;
  104. double            key_y;    /* user specified position for key */
  105. double            key_z;
  106. TBOOLEAN        is_log_x    = FALSE;
  107. TBOOLEAN        is_log_y    = FALSE;
  108. TBOOLEAN        is_log_z    = FALSE;
  109. double            base_log_x    = 0.0;
  110. double            base_log_y    = 0.0;
  111. double            base_log_z    = 0.0;
  112. double            log_base_log_x    = 0.0;
  113. double            log_base_log_y    = 0.0;
  114. double            log_base_log_z    = 0.0;
  115. FILE*            outfile;
  116. char            outstr[MAX_ID_LEN+1] = "STDOUT";
  117. TBOOLEAN        parametric    = FALSE;
  118. TBOOLEAN        polar        = FALSE;
  119. TBOOLEAN        hidden3d    = FALSE;
  120. TBOOLEAN        label_contours    = TRUE; /* different linestyles are used for contours when set */
  121. int            angles_format    = ANGLES_RADIANS;
  122. int            mapping3d    = MAP3D_CARTESIAN;
  123. int            samples        = SAMPLES; /* samples is always equal to samples_1 */
  124. int            samples_1    = SAMPLES;
  125. int            samples_2    = SAMPLES;
  126. int            iso_samples_1    = ISO_SAMPLES;
  127. int            iso_samples_2    = ISO_SAMPLES;
  128. float            xsize        = 1.0;  /* scale factor for size */
  129. float            ysize        = 1.0;  /* scale factor for size */
  130. float            zsize        = 1.0;  /* scale factor for size */
  131. float            surface_rot_z   = 30.0; /* Default 3d transform. */
  132. float            surface_rot_x   = 60.0;
  133. float            surface_scale   = 1.0;
  134. float            surface_zscale  = 1.0;
  135. int            term        = 0;        /* unknown term is 0 */
  136. char            term_options[MAX_LINE_LEN+1] = "";
  137. char            title[MAX_LINE_LEN+1] = "";
  138. char            xlabel[MAX_LINE_LEN+1] = "";
  139. char            ylabel[MAX_LINE_LEN+1] = "";
  140. char            zlabel[MAX_LINE_LEN+1] = "";
  141. int            time_xoffset    = 0;
  142. int            time_yoffset    = 0;
  143. int            title_xoffset    = 0;
  144. int            title_yoffset    = 0;
  145. int            xlabel_xoffset    = 0;
  146. int            xlabel_yoffset    = 0;
  147. int            ylabel_xoffset    = 0;
  148. int            ylabel_yoffset    = 0;
  149. int            zlabel_xoffset    = 0;
  150. int            zlabel_yoffset    = 0;
  151. double            rmin        = -0.0;
  152. double            rmax        =  10.0;
  153. double            tmin        = -5.0;
  154. double            tmax        =  5.0;
  155. double            umin        = -5.0;
  156. double            umax        = 5.0;
  157. double            vmin        = -5.0;
  158. double            vmax        = 5.0;
  159. double            xmin        = -10.0;
  160. double            xmax        = 10.0;
  161. double            ymin        = -10.0;
  162. double            ymax        = 10.0;
  163. double            zmin        = -10.0;
  164. double            zmax        = 10.0;
  165. double            loff        = 0.0;
  166. double            roff        = 0.0;
  167. double            toff        = 0.0;
  168. double            boff        = 0.0;
  169. int            draw_contour    = CONTOUR_NONE;
  170. int            contour_pts    = 5;
  171. int            contour_kind    = CONTOUR_KIND_LINEAR;
  172. int            contour_order    = 4;
  173. int            contour_levels    = 5;
  174. double            zero        = ZERO;    /* zero threshold, not 0! */
  175. int            levels_kind    = LEVELS_AUTO;
  176. double            levels_list[MAX_DISCRETE_LEVELS];  /* storage for z levels to draw contours at */
  177.  
  178. int            dgrid3d_row_fineness = 10;
  179. int            dgrid3d_col_fineness = 10;
  180. int            dgrid3d_norm_value = 1;
  181. TBOOLEAN        dgrid3d        = FALSE;
  182.  
  183. TBOOLEAN         xzeroaxis    = TRUE;
  184. TBOOLEAN         yzeroaxis    = TRUE;
  185.  
  186. TBOOLEAN         xtics        = TRUE;
  187. TBOOLEAN         ytics        = TRUE;
  188. TBOOLEAN         ztics        = TRUE;
  189.  
  190. float             ticslevel    = 0.5;
  191.  
  192. struct ticdef        xticdef        = {TIC_COMPUTED};
  193. struct ticdef        yticdef        = {TIC_COMPUTED};
  194. struct ticdef        zticdef        = {TIC_COMPUTED};
  195.  
  196. TBOOLEAN        tic_in        = TRUE;
  197.  
  198. struct text_label     *first_label    = NULL;
  199. struct arrow_def     *first_arrow    = NULL;
  200. #endif    /* THINK_C_1 */
  201.  
  202. /*** other things we need *****/
  203. /*** this is to be include bye THINK_C_1 and THINK_C_2 ***/
  204. #ifdef _Windows
  205. #include <string.h>
  206. #else
  207. #if !defined(ATARI) && !defined (AMIGA_SC_6_1)
  208. extern char *strcpy(),*strcat();
  209.  
  210. #ifdef THINK_C
  211. extern size_t strlen(const char *s);
  212. #else
  213. extern int      strlen();
  214. #endif
  215.  
  216. #endif
  217. #endif
  218.  
  219. #if defined(unix) || defined(PIPES)
  220. extern FILE *popen();
  221. #endif
  222.  
  223. /* input data, parsing variables */
  224. extern struct lexical_unit token[];
  225. extern char input_line[];
  226. extern int num_tokens, c_token;
  227. extern TBOOLEAN interactive;    /* from plot.c */
  228.  
  229. extern char replot_line[];
  230. extern struct udvt_entry *first_udv;
  231. extern TBOOLEAN is_3d_plot;
  232.  
  233. extern double magnitude(),real();
  234. extern struct value *const_express();
  235.  
  236. #ifdef _Windows
  237. extern FILE * open_printer();
  238. extern void close_printer();
  239. #endif
  240.  
  241. /******** Local functions ********/
  242. #ifdef THINK_C_1
  243. static void set_xyzlabel();
  244. static void set_label();
  245. static void set_nolabel();
  246. static void set_arrow();
  247. static void set_noarrow();
  248. static void load_tics();
  249. static void load_tic_user();
  250. static void free_marklist();
  251. static void load_tic_series();
  252. static void load_offsets();
  253. #endif
  254.  
  255. #ifdef THINK_C_2
  256. static void show_style(), show_range(), show_zero(), show_border(), show_dgrid3d();
  257. static void show_offsets(), show_output(), show_samples(), show_isosamples();
  258. static void show_view(), show_size(), show_title(), show_xlabel();
  259. static void show_angles(), show_boxwidth();
  260. static void show_ylabel(), show_zlabel(), show_xzeroaxis(), show_yzeroaxis();
  261. static void show_label(), show_arrow(), show_grid(), show_key();
  262. static void show_polar(), show_parametric(), show_tics(), show_ticdef();
  263. static void show_time(), show_term(), show_plot(), show_autoscale(), show_clip();
  264. static void show_contour(), show_mapping(), show_format(), show_logscale();
  265. static void show_variables(), show_surface(), show_hidden3d(), show_label_contours();
  266. #endif
  267.  
  268. #ifdef THINK_C_1
  269. static void delete_label();
  270. static int assign_label_tag();
  271. static void delete_arrow();
  272. static int assign_arrow_tag();
  273. static TBOOLEAN set_one(), set_two(), set_three();
  274. #endif
  275.  
  276. #ifdef THINK_C_2
  277. static TBOOLEAN show_one(), show_two();
  278. #endif
  279.  
  280. #ifdef THINK_C_1
  281. /******** The 'set' command ********/
  282. void
  283. set_command()
  284. {
  285. static char GPFAR setmess[] =
  286.     "valid set options:  'angles' '{no}arrow', {no}autoscale', \n\
  287.     '{no}border', 'boxwidth', '{no}clabel', '{no}clip', 'cntrparam', \n\
  288.         '{no}contour', 'data style', '{no}dgrid3d', 'dummy', 'format', \n\
  289.         'function style', '{no}grid', '{no}hidden3d', 'isosamples', '{no}key', \n\
  290.     '{no}label', '{no}logscale', 'mapping', 'offsets', 'output', \n\
  291.     '{no}parametric', '{no}polar', 'rrange', 'samples', 'size', \n\
  292.     '{no}surface', 'terminal', 'tics', 'ticslevel', '{no}time', 'title', \n\
  293.     'trange', 'urange', 'view', 'vrange', 'xlabel', 'xrange', '{no}xtics', \n\
  294.     'xmtics', 'xdtics', '{no}xzeroaxis', 'ylabel', 'yrange', '{no}ytics', \n\
  295.     'ymtics', 'ydtics', '{no}yzeroaxis', 'zero', '{no}zeroaxis', 'zlabel', \n\
  296.     'zrange', '{no}ztics', 'zmtics', 'zdtics'";
  297.  
  298.     c_token++;
  299.  
  300.     if (!set_one() && !set_two() && !set_three())
  301.     int_error(setmess, c_token);
  302. }
  303. #endif
  304.  
  305. #ifdef THINK_C_1
  306. /* return TRUE if a command match, FALSE if not */
  307. static TBOOLEAN
  308. set_one()
  309. {
  310.     if (almost_equals(c_token,"ar$row")) {
  311.         c_token++;
  312.         set_arrow();
  313.     }
  314.     else if (almost_equals(c_token,"noar$row")) {
  315.         c_token++;
  316.         set_noarrow();
  317.     }
  318.      else if (almost_equals(c_token,"au$toscale")) {
  319.         c_token++;
  320.         if (END_OF_COMMAND) {
  321.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = TRUE;
  322.         } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
  323.            autoscale_x = autoscale_y = TRUE;
  324.            c_token++;
  325.         } else if (equals(c_token, "r")) {
  326.            autoscale_r = TRUE;
  327.            c_token++;
  328.         } else if (equals(c_token, "t")) {
  329.            autoscale_t = TRUE;
  330.            c_token++;
  331.         } else if (equals(c_token, "x")) {
  332.            autoscale_x = TRUE;
  333.            c_token++;
  334.         } else if (equals(c_token, "y")) {
  335.            autoscale_y = TRUE;
  336.            c_token++;
  337.         } else if (equals(c_token, "z")) {
  338.            autoscale_z = TRUE;
  339.            c_token++;
  340.         }
  341.     } 
  342.     else if (almost_equals(c_token,"noau$toscale")) {
  343.         c_token++;
  344.         if (END_OF_COMMAND) {
  345.            autoscale_r=autoscale_t = autoscale_x = autoscale_y = autoscale_z = FALSE;
  346.         } else if (equals(c_token, "xy") || equals(c_token, "tyx")) {
  347.            autoscale_x = autoscale_y = FALSE;
  348.            c_token++;
  349.         } else if (equals(c_token, "r")) {
  350.            autoscale_r = FALSE;
  351.            c_token++;
  352.         } else if (equals(c_token, "t")) {
  353.            autoscale_t = FALSE;
  354.            c_token++;
  355.         } else if (equals(c_token, "x")) {
  356.            autoscale_x = FALSE;
  357.            c_token++;
  358.         } else if (equals(c_token, "y")) {
  359.            autoscale_y = FALSE;
  360.            c_token++;
  361.         } else if (equals(c_token, "z")) {
  362.            autoscale_z = FALSE;
  363.            c_token++;
  364.         }
  365.     } 
  366.     else if (almost_equals(c_token,"bor$der")) {
  367.         draw_border = TRUE;
  368.         c_token++;
  369.     }
  370.     else if (almost_equals(c_token,"nobor$der")) {
  371.         draw_border = FALSE;
  372.         c_token++;
  373.     }
  374.     else if (almost_equals(c_token,"box$width")) {
  375.         struct value a;
  376.         c_token++;
  377.         if (END_OF_COMMAND)
  378.             boxwidth = -1.0;
  379.         else
  380.             boxwidth = magnitude(const_express(&a));
  381.     }
  382.     else if (almost_equals(c_token,"c$lip")) {
  383.         c_token++;
  384.         if (END_OF_COMMAND)
  385.          /* assuming same as points */
  386.          clip_points = TRUE;
  387.         else if (almost_equals(c_token, "p$oints"))
  388.          clip_points = TRUE;
  389.         else if (almost_equals(c_token, "o$ne"))
  390.          clip_lines1 = TRUE;
  391.         else if (almost_equals(c_token, "t$wo"))
  392.          clip_lines2 = TRUE;
  393.         else
  394.          int_error("expecting 'points', 'one', or 'two'", c_token);
  395.         c_token++;
  396.     }
  397.     else if (almost_equals(c_token,"noc$lip")) {
  398.         c_token++;
  399.         if (END_OF_COMMAND) {
  400.            /* same as all three */
  401.            clip_points = FALSE;
  402.            clip_lines1 = FALSE;
  403.            clip_lines2 = FALSE;
  404.         } else if (almost_equals(c_token, "p$oints"))
  405.          clip_points = FALSE;
  406.         else if (almost_equals(c_token, "o$ne"))
  407.          clip_lines1 = FALSE;
  408.         else if (almost_equals(c_token, "t$wo"))
  409.          clip_lines2 = FALSE;
  410.         else
  411.          int_error("expecting 'points', 'one', or 'two'", c_token);
  412.         c_token++;
  413.     }
  414.     else if (almost_equals(c_token,"hi$dden3d")) {
  415. #ifdef LITE
  416.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  417. #else
  418.         hidden3d = TRUE;
  419. #endif /* LITE */
  420.         c_token++;
  421.     }
  422.     else if (almost_equals(c_token,"nohi$dden3d")) {
  423. #ifdef LITE
  424.         printf(" Hidden Line Removal Not Supported in LITE version\n");
  425. #else
  426.         hidden3d = FALSE;
  427. #endif /* LITE */
  428.         c_token++;
  429.     }
  430.      else if (almost_equals(c_token,"cla$bel")) {
  431.          label_contours = TRUE;
  432.          c_token++;
  433.      }
  434.      else if (almost_equals(c_token,"nocla$bel")) {
  435.          label_contours = FALSE;
  436.          c_token++;
  437.       }
  438.     else if (almost_equals(c_token,"ma$pping3d")) {
  439.         c_token++;
  440.         if (END_OF_COMMAND)
  441.          /* assuming same as points */
  442.          mapping3d = MAP3D_CARTESIAN;
  443.         else if (almost_equals(c_token, "ca$rtesian"))
  444.          mapping3d = MAP3D_CARTESIAN;
  445.         else if (almost_equals(c_token, "s$pherical"))
  446.          mapping3d = MAP3D_SPHERICAL;
  447.         else if (almost_equals(c_token, "cy$lindrical"))
  448.          mapping3d = MAP3D_CYLINDRICAL;
  449.         else
  450.          int_error("expecting 'cartesian', 'spherical', or 'cylindrical'", c_token);
  451.         c_token++;
  452.     }
  453.     else if (almost_equals(c_token,"co$ntour")) {
  454.         c_token++;
  455.         if (END_OF_COMMAND)
  456.          /* assuming same as points */
  457.          draw_contour = CONTOUR_BASE;
  458.         else if (almost_equals(c_token, "ba$se"))
  459.          draw_contour = CONTOUR_BASE;
  460.         else if (almost_equals(c_token, "s$urface"))
  461.          draw_contour = CONTOUR_SRF;
  462.         else if (almost_equals(c_token, "bo$th"))
  463.          draw_contour = CONTOUR_BOTH;
  464.         else
  465.          int_error("expecting 'base', 'surface', or 'both'", c_token);
  466.         c_token++;
  467.     }
  468.     else if (almost_equals(c_token,"noco$ntour")) {
  469.         c_token++;
  470.         draw_contour = CONTOUR_NONE;
  471.     }
  472.     else if (almost_equals(c_token,"cntrp$aram")) {
  473.         struct value a;
  474.  
  475.         c_token++;
  476.         if (END_OF_COMMAND) {
  477.          /* assuming same as defaults */
  478.          contour_pts = 5;
  479.          contour_kind = CONTOUR_KIND_LINEAR;
  480.          contour_order = 4;
  481.          contour_levels = 5;
  482.           levels_kind = LEVELS_AUTO;
  483.         }
  484.         else if (almost_equals(c_token, "p$oints")) {
  485.          c_token++;
  486.          contour_pts = (int) real(const_express(&a));
  487.         }
  488.         else if (almost_equals(c_token, "li$near")) {
  489.          c_token++;
  490.          contour_kind = CONTOUR_KIND_LINEAR;
  491.         }
  492.         else if (almost_equals(c_token, "c$ubicspline")) {
  493.          c_token++;
  494.          contour_kind = CONTOUR_KIND_CUBIC_SPL;
  495.         }
  496.         else if (almost_equals(c_token, "b$spline")) {
  497.          c_token++;
  498.          contour_kind = CONTOUR_KIND_BSPLINE;
  499.         }
  500.  
  501.            else if (almost_equals(c_token, "le$vels")) {
  502.                int i=0;  /* local counter */
  503.                c_token++;
  504.             /*  RKC: I have modified the next two:
  505.              *   to use commas to separate list elements as in xtics
  506.               *   so that incremental lists start,incr[,end]as in "
  507.               */
  508.                if (almost_equals(c_token, "di$screte")) {
  509.                   levels_kind = LEVELS_DISCRETE;
  510.                   c_token++;
  511.                 if(END_OF_COMMAND)
  512.                  int_error("expecting discrete level", c_token);
  513.                 else
  514.                   levels_list[i++] = real(const_express(&a));
  515.                 while(!END_OF_COMMAND){
  516.                   if (!equals(c_token, ","))
  517.                     int_error("expecting comma to separate discrete levels", c_token);
  518.                   c_token++;
  519.                   levels_list[i++] =  real(const_express(&a));
  520.                 }
  521.                   contour_levels = i;
  522.                }
  523.                else if (almost_equals(c_token, "in$cremental")) {
  524.                   levels_kind = LEVELS_INCREMENTAL;
  525.                   c_token++;
  526.                 levels_list[i++] =  real(const_express(&a));
  527.                 if (!equals(c_token, ","))
  528.                   int_error("expecting comma to separate start,incr levels", c_token);
  529.                 c_token++;
  530.                 if((levels_list[i++] = real(const_express(&a)))==0)
  531.                   int_error("increment cannot be 0", c_token);
  532.                  if(!END_OF_COMMAND){
  533.                   if (!equals(c_token, ","))
  534.                     int_error("expecting comma to separate incr,stop levels", c_token);
  535.                   c_token++;
  536.                  contour_levels = (real(const_express(&a))-levels_list[0])/levels_list[1];
  537.                   }
  538.                }
  539.                else if (almost_equals(c_token, "au$to")) {
  540.                    levels_kind = LEVELS_AUTO;
  541.                  c_token++;
  542.                  if(!END_OF_COMMAND)
  543.                      contour_levels = (int) real(const_express(&a));
  544.              }
  545.              else {
  546.               if(levels_kind == LEVELS_DISCRETE)
  547.                 int_error("Levels type is discrete, ignoring new number of contour levels", c_token);
  548.                 contour_levels = (int) real(const_express(&a));
  549.             }
  550.          }
  551.         else if (almost_equals(c_token, "o$rder")) {
  552.          int order;
  553.          c_token++;
  554.          order = (int) real(const_express(&a));
  555.          if ( order < 2 || order > 10 )
  556.              int_error("bspline order must be in [2..10] range.", c_token);
  557.          contour_order = order;
  558.         }
  559.         else
  560.          int_error("expecting 'linear', 'cubicspline', 'bspline', 'points', 'levels' or 'order'", c_token);
  561.         c_token++;
  562.     }
  563.     else if (almost_equals(c_token,"da$ta")) {
  564.         c_token++;
  565.         if (!almost_equals(c_token,"s$tyle"))
  566.             int_error("expecting keyword 'style'",c_token);
  567.         data_style = get_style();
  568.     }
  569.     else if (almost_equals(c_token,"dg$rid3d")) {
  570.         int i;
  571.         TBOOLEAN was_comma = TRUE;
  572.         int local_vals[3];
  573.         struct value a;
  574.  
  575.         local_vals[0] = dgrid3d_row_fineness;
  576.         local_vals[1] = dgrid3d_col_fineness;
  577.         local_vals[2] = dgrid3d_norm_value;
  578.         c_token++;
  579.         for (i = 0; i < 3 && !(END_OF_COMMAND);) {
  580.             if (equals(c_token,",")) {
  581.                 if (was_comma) i++;
  582.                 was_comma = TRUE;
  583.                 c_token++;
  584.             }
  585.             else {
  586.                 if (!was_comma)
  587.                     int_error("',' expected",c_token);
  588.                 local_vals[i] = real(const_express(&a));
  589.                 i++;
  590.                 was_comma = FALSE;
  591.             }
  592.         }
  593.  
  594.  
  595.         if (local_vals[0] < 2 || local_vals[0] > 1000)
  596.             int_error("Row size must be in [2:1000] range; size unchanged",
  597.                   c_token);
  598.         if (local_vals[1] < 2 || local_vals[1] > 1000)
  599.             int_error("Col size must be in [2:1000] range; size unchanged",
  600.                   c_token);
  601.         if (local_vals[2] < 1 || local_vals[2] > 100)
  602.             int_error("Norm must be in [1:100] range; norm unchanged", c_token);
  603.  
  604.         dgrid3d_row_fineness = local_vals[0];
  605.         dgrid3d_col_fineness = local_vals[1];
  606.         dgrid3d_norm_value = local_vals[2];
  607.         dgrid3d = TRUE;
  608.     }
  609.     else if (almost_equals(c_token,"nodg$rid3d")) {
  610.         c_token++;
  611.         dgrid3d = FALSE;
  612.     }
  613.     else if (almost_equals(c_token,"du$mmy")) {
  614.         c_token++;
  615.         if (END_OF_COMMAND)
  616.             int_error("expecting dummy variable name", c_token);
  617.         else {
  618.             if (!equals(c_token,","))
  619.                 copy_str(dummy_var[0],c_token++);
  620.             if (!END_OF_COMMAND && equals(c_token,",")) {
  621.                 c_token++;
  622.                 if (END_OF_COMMAND)
  623.                     int_error("expecting second dummy variable name", c_token);
  624.                 copy_str(dummy_var[1],c_token++);
  625.                 }
  626.         }
  627.     }
  628.     else if (almost_equals(c_token,"fo$rmat")) {
  629.         TBOOLEAN setx, sety, setz;
  630.         c_token++;
  631.         if (equals(c_token,"x")) {
  632.             setx = TRUE; sety = setz = FALSE;
  633.             c_token++;
  634.         }
  635.         else if (equals(c_token,"y")) {
  636.             setx = setz = FALSE; sety = TRUE;
  637.             c_token++;
  638.         }
  639.         else if (equals(c_token,"z")) {
  640.             setx = sety = FALSE; setz = TRUE;
  641.             c_token++;
  642.         }
  643.         else if (equals(c_token,"xy") || equals(c_token,"yx")) {
  644.             setx = sety = TRUE; setz = FALSE;
  645.             c_token++;
  646.         }
  647.         else if (isstring(c_token) || END_OF_COMMAND) {
  648.             /* Assume he wants all */
  649.             setx = sety = setz = TRUE;
  650.         }
  651.         if (END_OF_COMMAND) {
  652.             if (setx)
  653.                 (void) strcpy(xformat,DEF_FORMAT);
  654.             if (sety)
  655.                 (void) strcpy(yformat,DEF_FORMAT);
  656.             if (setz)
  657.                 (void) strcpy(zformat,DEF_FORMAT);
  658.         }
  659.         else {
  660.             if (!isstring(c_token))
  661.               int_error("expecting format string",c_token);
  662.             else {
  663.                 if (setx)
  664.                  quote_str(xformat,c_token);
  665.                 if (sety)
  666.                  quote_str(yformat,c_token);
  667.                 if (setz)
  668.                  quote_str(zformat,c_token);
  669.                 c_token++;
  670.             }
  671.         }
  672.     }
  673.     else if (almost_equals(c_token,"fu$nction")) {
  674.         c_token++;
  675.         if (!almost_equals(c_token,"s$tyle"))
  676.             int_error("expecting keyword 'style'",c_token);
  677.         func_style = get_style();
  678.     }
  679.     else if (almost_equals(c_token,"la$bel")) {
  680.         c_token++;
  681.         set_label();
  682.     }
  683.     else if (almost_equals(c_token,"nola$bel")) {
  684.         c_token++;
  685.         set_nolabel();
  686.     }
  687.     else if (almost_equals(c_token,"lo$gscale")) {
  688.         c_token++;
  689.         if (END_OF_COMMAND) {
  690.         is_log_x = is_log_y = is_log_z = TRUE;
  691.         base_log_x = base_log_y = base_log_z = 10.0;
  692.         log_base_log_x = log_base_log_y = log_base_log_z = log(10.0);
  693.         } else {
  694.         TBOOLEAN change_x = FALSE;
  695.         TBOOLEAN change_y = FALSE;
  696.         TBOOLEAN change_z = FALSE;
  697.         if (chr_in_str(c_token, 'x'))
  698.             change_x = TRUE;
  699.         if (chr_in_str(c_token, 'y'))
  700.             change_y = TRUE;
  701.         if (chr_in_str(c_token, 'z'))
  702.             change_z = TRUE;
  703.         c_token++;
  704.                 if (END_OF_COMMAND) {
  705.             if (change_x) {
  706.             is_log_x = TRUE;
  707.             base_log_x = 10.0;
  708.             log_base_log_x = log(10.0);
  709.             }
  710.             if (change_y) {
  711.             is_log_y = TRUE;
  712.             base_log_y = 10.0;
  713.             log_base_log_y = log(10.0);
  714.             }
  715.             if (change_z) {
  716.             is_log_z = TRUE;
  717.             base_log_z = 10.0;
  718.             log_base_log_z = log(10.0);
  719.             }
  720.         } else {
  721.             struct value a;
  722.             double newbase = magnitude(const_express(&a));
  723.             c_token++;
  724.             if (newbase < 1.1)
  725.             int_error("log base must be >= 1.1; logscale unchanged",
  726.                 c_token);
  727.             else {
  728.             if (change_x) {
  729.                 is_log_x = TRUE;
  730.                 base_log_x = newbase;
  731.                 log_base_log_x = log(newbase);
  732.             }
  733.             if (change_y) {
  734.                 is_log_y = TRUE;
  735.                 base_log_y = newbase;
  736.                 log_base_log_y = log(newbase);
  737.             }
  738.             if (change_z) {
  739.                 is_log_z = TRUE;
  740.                 base_log_z = newbase;
  741.                 log_base_log_z = log(newbase);
  742.             }
  743.             }
  744.         }
  745.         }
  746.     }
  747.     else if (almost_equals(c_token,"nolo$gscale")) {
  748.         c_token++;
  749.         if (END_OF_COMMAND) {
  750.         is_log_x = is_log_y = is_log_z = FALSE;
  751.         } else {
  752.         if (chr_in_str(c_token, 'x')) {
  753.             is_log_x = FALSE;
  754.             base_log_x = 0.0;
  755.             log_base_log_x = 0.0;
  756.                 }
  757.         if (chr_in_str(c_token, 'y')) {
  758.             is_log_y = FALSE;
  759.             base_log_y = 0.0;
  760.             log_base_log_y = 0.0;
  761.                 }
  762.         if (chr_in_str(c_token, 'z')) {
  763.             is_log_z = FALSE;
  764.             base_log_z = 0.0;
  765.             log_base_log_z = 0.0;
  766.                 }
  767.         c_token++;
  768.         }
  769.     } 
  770.     else if (almost_equals(c_token,"of$fsets")) {
  771.         c_token++;
  772.         if (END_OF_COMMAND) {
  773.             loff = roff = toff = boff = 0.0;  /* Reset offsets */
  774.         }
  775.         else {
  776.             load_offsets (&loff,&roff,&toff,&boff);
  777.         }
  778.     }
  779.     else
  780.         return(FALSE);    /* no command match */
  781.     return(TRUE);
  782. }
  783. #endif
  784.  
  785. #ifdef THINK_C_1
  786. /* return TRUE if a command match, FALSE if not */
  787. static TBOOLEAN
  788. set_two()
  789. {
  790.      char testfile[MAX_LINE_LEN+1];
  791. #if defined(unix) || defined(PIPES)
  792.      static TBOOLEAN pipe_open = FALSE;
  793. #endif /* unix || PIPES */
  794.  
  795.     if (almost_equals(c_token,"o$utput")) {
  796.         register FILE *f;
  797.  
  798.         c_token++;
  799.         if (term && term_init)
  800.             (*term_tbl[term].reset)();
  801.         if (END_OF_COMMAND) {    /* no file specified */
  802.              UP_redirect (4);
  803.             if (outfile != stdout) { /* Never close stdout */
  804. #if defined(unix) || defined(PIPES)
  805.                 if ( pipe_open ) {
  806.                     (void) pclose(outfile);
  807.                     pipe_open = FALSE;
  808.                 } else
  809. #endif /* unix || PIPES */
  810. #ifdef _Windows
  811.                   if ( !stricmp(outstr,"'PRN'") )
  812.                     close_printer();
  813.                   else
  814. #endif
  815.                     (void) fclose(outfile);
  816.             }
  817.             outfile = stdout; /* Don't dup... */
  818.             term_init = FALSE;
  819.             (void) strcpy(outstr,"STDOUT");
  820.         } else if (!isstring(c_token))
  821. #ifdef THINK_C
  822.             {     Point where={97,103};
  823.                 SFReply reply;
  824.                 
  825.                 SFPutFile(where,NULL, "\pUntitled",NULL, &reply);
  826.                 if( (reply.good) && (SetVol(reply.fName,reply.vRefNum) == noErr)){
  827.                     PtoCstr((char *) reply.fName);
  828.                     strcpy(testfile,(char *) reply.fName);
  829.                     if ((f = fopen(testfile,"w")) == (FILE *)NULL) {
  830.                       os_error("cannot open file; output not changed",c_token);
  831.                     }
  832.                     if (outfile != stdout) /* Never close stdout */
  833.                         (void) fclose(outfile);
  834.                     outfile = f;
  835.                     term_init = FALSE;
  836.                     outstr[0] = '\'';
  837.                     (void) strcat(strcpy(outstr+1,testfile),"'");
  838.                      UP_redirect (1);
  839.                 }
  840.                 else{
  841.                     int_error("expecting filename",c_token);
  842.                 }
  843.             }
  844. #else
  845.             int_error("expecting filename",c_token);
  846. #endif
  847.         else {
  848.             quote_str(testfile,c_token);
  849. #if defined(unix) || defined(PIPES)
  850.             if ( *testfile == '|' ) {
  851.               if ((f = popen(testfile+1,"w")) == (FILE *)NULL)
  852.                 os_error("cannot create pipe; output not changed",c_token);
  853.               else
  854.                 pipe_open = TRUE;
  855.             } else
  856. #endif /* unix || PIPES */
  857. #ifdef _Windows
  858.             if ( !stricmp(outstr,"'PRN'") ) {
  859.                 /* we can't call open_printer() while printer is open, so */
  860.                 close_printer();    /* close printer immediately if open */
  861.                 outfile = stdout;    /* and reset output to stdout */
  862.                 term_init = FALSE;
  863.                 (void) strcpy(outstr,"STDOUT");
  864.             }
  865.             if ( !stricmp(testfile,"PRN") ) {
  866.               if ((f = open_printer()) == (FILE *)NULL)
  867.                 os_error("cannot open printer temporary file; output may have changed",c_token);
  868.             } else
  869. #endif
  870.               if ((f = fopen(testfile,"w")) == (FILE *)NULL)
  871.                 os_error("cannot open file; output not changed",c_token);
  872.             if (outfile != stdout) /* Never close stdout */
  873. #if defined(unix) || defined(PIPES)
  874.                 if( pipe_open ) {
  875.                 (void) pclose(outfile);
  876.                 pipe_open=FALSE;
  877.                 } else
  878. #endif /* unix || PIPES */
  879.                 (void) fclose(outfile);
  880.             outfile = f;
  881.             term_init = FALSE;
  882.             outstr[0] = '\'';
  883.             (void) strcat(strcpy(outstr+1,testfile),"'");
  884.              UP_redirect (1);
  885.         }
  886.         c_token++;
  887.     }
  888.     else if (almost_equals(c_token,"tit$le")) {
  889.         set_xyzlabel(title,&title_xoffset,&title_yoffset);
  890.     }
  891.     else if (almost_equals(c_token,"xl$abel")) {
  892.         set_xyzlabel(xlabel,&xlabel_xoffset,&xlabel_yoffset);
  893.     }
  894.     else if (almost_equals(c_token,"yl$abel")) {
  895.         set_xyzlabel(ylabel,&ylabel_xoffset,&ylabel_yoffset);
  896.     }
  897.     else if (almost_equals(c_token,"zl$abel")) {
  898.         set_xyzlabel(zlabel,&zlabel_xoffset,&zlabel_yoffset);
  899.     }
  900.     else if (almost_equals(c_token,"xzero$axis")) {
  901.         c_token++;
  902.         xzeroaxis = TRUE;
  903.     } 
  904.     else if (almost_equals(c_token,"yzero$axis")) {
  905.         c_token++;
  906.         yzeroaxis = TRUE;
  907.     } 
  908.     else if (almost_equals(c_token,"zeroa$xis")) {
  909.         c_token++;
  910.         yzeroaxis = TRUE;
  911.         xzeroaxis = TRUE;
  912.     } 
  913.     else if (almost_equals(c_token,"noxzero$axis")) {
  914.         c_token++;
  915.         xzeroaxis = FALSE;
  916.     } 
  917.     else if (almost_equals(c_token,"noyzero$axis")) {
  918.         c_token++;
  919.         yzeroaxis = FALSE;
  920.     } 
  921.     else if (almost_equals(c_token,"nozero$axis")) {
  922.         c_token++;
  923.         xzeroaxis = FALSE;
  924.         yzeroaxis = FALSE;
  925.     } 
  926.     else if (almost_equals(c_token,"par$ametric")) {
  927.         if (!parametric) {
  928.            parametric = TRUE;
  929.            strcpy (dummy_var[0], "t");
  930.            strcpy (dummy_var[1], "y");
  931.            if (interactive)
  932.              (void) fprintf(stderr,"\n\tdummy variable is t for curves, u/v for surfaces\n");
  933.         }
  934.         c_token++;
  935.     }
  936.     else if (almost_equals(c_token,"nopar$ametric")) {
  937.         if (parametric) {
  938.            parametric = FALSE;
  939.            strcpy (dummy_var[0], "x");
  940.            strcpy (dummy_var[1], "y");
  941.            if (interactive)
  942.              (void) fprintf(stderr,"\n\tdummy variable is x for curves, x/y for surfaces\n");
  943.         }
  944.         c_token++;
  945.     }
  946.     else if (almost_equals(c_token,"pol$ar")) {
  947.         if (!polar) {
  948.             polar = TRUE;
  949.             if (parametric) {
  950.                 tmin = 0.0;
  951.                 tmax = 2*Pi;
  952.             } else if (angles_format == ANGLES_DEGREES) {
  953.                 xmin = 0.0;
  954.                 xmax = 360.0;
  955.             } else {
  956.                 xmin = 0.0;
  957.                 xmax = 2*Pi;
  958.             }
  959.         }
  960.         c_token++;
  961.     }
  962.     else if (almost_equals(c_token,"nopo$lar")) {
  963.         if (polar) {
  964.             polar = FALSE;
  965.             if (parametric) {
  966.                 tmin = -5.0;
  967.                 tmax = 5.0;
  968.             } else {
  969.                 xmin = -10.0;
  970.                 xmax = 10.0;
  971.             }
  972.         }
  973.         c_token++;
  974.     }
  975.     else if (almost_equals(c_token,"an$gles")) {
  976.         c_token++;
  977.         if (END_OF_COMMAND) {
  978.         /* assuming same as defaults */
  979.         angles_format = ANGLES_RADIANS;
  980.         }
  981.         else if (almost_equals(c_token, "r$adians")) {
  982.         angles_format = ANGLES_RADIANS;
  983.         c_token++;
  984.         }
  985.         else if (almost_equals(c_token, "d$egrees")) {
  986.         angles_format = ANGLES_DEGREES;
  987.         c_token++;
  988.         }
  989.         else
  990.          int_error("expecting 'radians' or 'degrees'", c_token);
  991.     }
  992.     else if (almost_equals(c_token,"g$rid")) {
  993.         grid = TRUE;
  994.         c_token++;
  995.     }
  996.     else if (almost_equals(c_token,"nog$rid")) {
  997.         grid = FALSE;
  998.         c_token++;
  999.     }
  1000.     else if (almost_equals(c_token,"su$rface")) {
  1001.         draw_surface = TRUE;
  1002.         c_token++;
  1003.     }
  1004.     else if (almost_equals(c_token,"nosu$rface")) {
  1005.         draw_surface = FALSE;
  1006.         c_token++;
  1007.     }
  1008.     else if (almost_equals(c_token,"k$ey")) {
  1009.         struct value a;
  1010.         c_token++;
  1011.         if (END_OF_COMMAND) {
  1012.             key = -1;
  1013.         } 
  1014.         else {
  1015.             key_x = real(const_express(&a));
  1016.             if (!equals(c_token,","))
  1017.                 int_error("',' expected",c_token);
  1018.             c_token++;
  1019.             key_y = real(const_express(&a));
  1020.             if (equals(c_token,","))
  1021.             {
  1022.                     c_token++;
  1023.                 key_z = real(const_express(&a));
  1024.             }
  1025.             key = 1;
  1026.         } 
  1027.     }
  1028.     else if (almost_equals(c_token,"nok$ey")) {
  1029.         key = 0;
  1030.         c_token++;
  1031.     }
  1032.     else if (almost_equals(c_token,"tic$s")) {
  1033.         tic_in = TRUE;
  1034.         c_token++;
  1035.         if (almost_equals(c_token,"i$n")) {
  1036.             tic_in = TRUE;
  1037.             c_token++;
  1038.         }
  1039.         else if (almost_equals(c_token,"o$ut")) {
  1040.             tic_in = FALSE;
  1041.             c_token++;
  1042.         }
  1043.     }
  1044.      else if (almost_equals(c_token,"xmt$ics")) {
  1045.      xtics = TRUE;
  1046.      c_token++;
  1047.      if(xticdef.type == TIC_USER){
  1048.          free_marklist(xticdef.def.user);
  1049.          xticdef.def.user = NULL;
  1050.      }
  1051.     xticdef.type = TIC_MONTH;
  1052.      }
  1053.      else if (almost_equals(c_token,"xdt$ics")) {
  1054.      xtics = TRUE;
  1055.      c_token++;
  1056.      if(xticdef.type == TIC_USER){
  1057.          free_marklist(xticdef.def.user);
  1058.          xticdef.def.user = NULL;
  1059.      }
  1060.     xticdef.type = TIC_DAY;
  1061.      }
  1062.      else if (almost_equals(c_token,"xt$ics")) {
  1063.         xtics = TRUE;
  1064.         c_token++;
  1065.         if (END_OF_COMMAND) { /* reset to default */
  1066.            if (xticdef.type == TIC_USER) {
  1067.               free_marklist(xticdef.def.user);
  1068.               xticdef.def.user = NULL;
  1069.            }
  1070.            xticdef.type = TIC_COMPUTED;
  1071.         }
  1072.         else
  1073.          load_tics(&xticdef);
  1074.     } 
  1075.      else if (almost_equals(c_token,"noxt$ics")) {
  1076.         xtics = FALSE;
  1077.         c_token++;
  1078.     } 
  1079.      else if (almost_equals(c_token,"ymt$ics")) {
  1080.      ytics = TRUE;
  1081.      c_token++;
  1082.      if(yticdef.type == TIC_USER){
  1083.          free_marklist(yticdef.def.user);
  1084.          yticdef.def.user = NULL;
  1085.      }
  1086.     yticdef.type = TIC_MONTH;
  1087.      }
  1088.      else if (almost_equals(c_token,"ydt$ics")) {
  1089.      ytics = TRUE;
  1090.      c_token++;
  1091.      if(yticdef.type == TIC_USER){
  1092.          free_marklist(yticdef.def.user);
  1093.          yticdef.def.user = NULL;
  1094.      }
  1095.     yticdef.type = TIC_DAY;
  1096.      }
  1097.      else if (almost_equals(c_token,"yt$ics")) {
  1098.         ytics = TRUE;
  1099.         c_token++;
  1100.         if (END_OF_COMMAND) { /* reset to default */
  1101.            if (yticdef.type == TIC_USER) {
  1102.               free_marklist(yticdef.def.user);
  1103.               yticdef.def.user = NULL;
  1104.            }
  1105.            yticdef.type = TIC_COMPUTED;
  1106.         }
  1107.         else
  1108.          load_tics(&yticdef);
  1109.     } 
  1110.      else if (almost_equals(c_token,"noyt$ics")) {
  1111.         ytics = FALSE;
  1112.         c_token++;
  1113.     } 
  1114.      else if (almost_equals(c_token,"zmt$ics")) {
  1115.      ztics = TRUE;
  1116.      c_token++;
  1117.      if(zticdef.type == TIC_USER){
  1118.          free_marklist(zticdef.def.user);
  1119.          zticdef.def.user = NULL;
  1120.      }
  1121.     zticdef.type = TIC_MONTH;
  1122.      }
  1123.      else if (almost_equals(c_token,"zdt$ics")) {
  1124.      ztics = TRUE;
  1125.      c_token++;
  1126.      if(zticdef.type == TIC_USER){
  1127.          free_marklist(zticdef.def.user);
  1128.          zticdef.def.user = NULL;
  1129.      }
  1130.     zticdef.type = TIC_DAY;
  1131.      }
  1132.      else if (almost_equals(c_token,"zt$ics")) {
  1133.         ztics = TRUE;
  1134.         c_token++;
  1135.         if (END_OF_COMMAND) { /* reset to default */
  1136.            if (zticdef.type == TIC_USER) {
  1137.               free_marklist(zticdef.def.user);
  1138.               zticdef.def.user = NULL;
  1139.            }
  1140.            zticdef.type = TIC_COMPUTED;
  1141.         }
  1142.         else
  1143.          load_tics(&zticdef);
  1144.     } 
  1145.      else if (almost_equals(c_token,"nozt$ics")) {
  1146.         ztics = FALSE;
  1147.         c_token++;
  1148.     } 
  1149.     else if (almost_equals(c_token,"ticsl$evel")) {
  1150.         double tlvl;
  1151.         struct value a;
  1152.  
  1153.         c_token++;
  1154.         tlvl = real(const_express(&a));
  1155.         if (tlvl < 0.0)
  1156.             int_error("tics level must be > 0; ticslevel unchanged",
  1157.                 c_token);
  1158.         else {
  1159.             ticslevel = tlvl;
  1160.         }
  1161.     }
  1162.     else
  1163.     return(FALSE);    /* no command match */
  1164.  
  1165.     return(TRUE);
  1166. }
  1167. #endif
  1168.  
  1169. #ifdef THINK_C_1
  1170. /* return TRUE if a command match, FALSE if not */
  1171. static TBOOLEAN
  1172. set_three()
  1173. {
  1174.      if (almost_equals(c_token,"sa$mples")) {
  1175.         register int tsamp1, tsamp2;
  1176.         struct value a;
  1177.  
  1178.         c_token++;
  1179.         tsamp1 = (int)magnitude(const_express(&a));
  1180.         tsamp2 = tsamp1;
  1181.         if (!END_OF_COMMAND) {
  1182.             if (!equals(c_token,","))
  1183.                 int_error("',' expected",c_token);
  1184.             c_token++;
  1185.             tsamp2 = (int)magnitude(const_express(&a));
  1186.         }
  1187.         if (tsamp1 < 2 || tsamp2 < 2)
  1188.             int_error("sampling rate must be > 1; sampling unchanged",
  1189.                 c_token);
  1190.         else {
  1191.                 extern struct surface_points *first_3dplot;
  1192.             register struct surface_points *f_3dp = first_3dplot;
  1193.  
  1194.             first_3dplot = NULL;
  1195.             sp_free(f_3dp);
  1196.  
  1197.             samples = tsamp1;
  1198.             samples_1 = tsamp1;
  1199.             samples_2 = tsamp2;
  1200.         }
  1201.     }
  1202.     else if (almost_equals(c_token,"isosa$mples")) {
  1203.         register int tsamp1, tsamp2;
  1204.         struct value a;
  1205.  
  1206.         c_token++;
  1207.         tsamp1 = (int)magnitude(const_express(&a));
  1208.         tsamp2 = tsamp1;
  1209.         if (!END_OF_COMMAND) {
  1210.             if (!equals(c_token,","))
  1211.                 int_error("',' expected",c_token);
  1212.             c_token++;
  1213.             tsamp2 = (int)magnitude(const_express(&a));
  1214.         }
  1215.         if (tsamp1 < 2 || tsamp2 < 2)
  1216.             int_error("sampling rate must be > 1; sampling unchanged",
  1217.                 c_token);
  1218.         else {
  1219.                 extern struct curve_points *first_plot;
  1220.                 extern struct surface_points *first_3dplot;
  1221.             register struct curve_points *f_p = first_plot;
  1222.             register struct surface_points *f_3dp = first_3dplot;
  1223.  
  1224.             first_plot = NULL;
  1225.             first_3dplot = NULL;
  1226.             cp_free(f_p);
  1227.             sp_free(f_3dp);
  1228.  
  1229.             iso_samples_1 = tsamp1;
  1230.             iso_samples_2 = tsamp2;
  1231.         }
  1232.     }
  1233.     else if (almost_equals(c_token,"si$ze")) {
  1234.         struct value s;
  1235.         c_token++;
  1236.         if (END_OF_COMMAND) {
  1237.             xsize = 1.0;
  1238.             ysize = 1.0;
  1239.         } 
  1240.         else {
  1241.                 xsize=real(const_express(&s));
  1242.                 if (!equals(c_token,","))
  1243.                     int_error("',' expected",c_token);
  1244.                 c_token++;
  1245.                 ysize=real(const_express(&s));
  1246.         } 
  1247.     } 
  1248.     else if (almost_equals(c_token,"t$erminal")) {
  1249.         c_token++;
  1250.         if (END_OF_COMMAND) {
  1251.             list_terms();
  1252.             screen_ok = FALSE;
  1253.         }
  1254.         else {
  1255.             if (term && term_init) {
  1256.                 (*term_tbl[term].reset)();
  1257.                 (void) fflush(outfile);
  1258.             }
  1259.             term = set_term(c_token);
  1260.             c_token++;
  1261.  
  1262.             /* get optional mode parameters */
  1263.             if (term)
  1264.                 (*term_tbl[term].options)();
  1265.             if (interactive && *term_options)
  1266.                 fprintf(stderr,"Options are '%s'\n",term_options);
  1267.         }
  1268.     }
  1269.     else if (almost_equals(c_token,"tim$e")) {
  1270.         timedate = TRUE;
  1271.         c_token++;
  1272.         if (!END_OF_COMMAND) {
  1273.             struct value a;
  1274.  
  1275.             /* We have x,y offsets specified */
  1276.             if (!equals(c_token,","))
  1277.                 time_xoffset = (int)real(const_express(&a));
  1278.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1279.                 c_token++;
  1280.                 time_yoffset = (int)real(const_express(&a));
  1281.             }
  1282.         }
  1283.     }
  1284.     else if (almost_equals(c_token,"not$ime")) {
  1285.         timedate = FALSE;
  1286.         c_token++;
  1287.     }
  1288.     else if (almost_equals(c_token,"rr$ange")) {
  1289.          TBOOLEAN changed;
  1290.         c_token++;
  1291.         if (!equals(c_token,"["))
  1292.             int_error("expecting '['",c_token);
  1293.         c_token++;
  1294.         changed = load_range(&rmin,&rmax);
  1295.         if (!equals(c_token,"]"))
  1296.           int_error("expecting ']'",c_token);
  1297.         c_token++;
  1298.         if (changed)
  1299.           autoscale_r = FALSE;
  1300.     }
  1301.     else if (almost_equals(c_token,"tr$ange")) {
  1302.          TBOOLEAN changed;
  1303.         c_token++;
  1304.         if (!equals(c_token,"["))
  1305.             int_error("expecting '['",c_token);
  1306.         c_token++;
  1307.         changed = load_range(&tmin,&tmax);
  1308.         if (!equals(c_token,"]"))
  1309.           int_error("expecting ']'",c_token);
  1310.         c_token++;
  1311.         if (changed)
  1312.           autoscale_t = FALSE;
  1313.     }
  1314.     else if (almost_equals(c_token,"ur$ange")) {
  1315.          TBOOLEAN changed;
  1316.         c_token++;
  1317.         if (!equals(c_token,"["))
  1318.             int_error("expecting '['",c_token);
  1319.         c_token++;
  1320.         changed = load_range(&umin,&umax);
  1321.         if (!equals(c_token,"]"))
  1322.           int_error("expecting ']'",c_token);
  1323.         c_token++;
  1324.         if (changed)
  1325.           autoscale_u = FALSE;
  1326.     }
  1327.     else if (almost_equals(c_token,"vi$ew")) {
  1328.         int i;
  1329.         TBOOLEAN was_comma = TRUE;
  1330.         double local_vals[4];
  1331.         struct value a;
  1332.  
  1333.         local_vals[0] = surface_rot_x;
  1334.         local_vals[1] = surface_rot_z;
  1335.         local_vals[2] = surface_scale;
  1336.         local_vals[3] = surface_zscale;
  1337.         c_token++;
  1338.         for (i = 0; i < 4 && !(END_OF_COMMAND);) {
  1339.             if (equals(c_token,",")) {
  1340.                 if (was_comma) i++;
  1341.                 was_comma = TRUE;
  1342.                 c_token++;
  1343.             }
  1344.             else {
  1345.                 if (!was_comma)
  1346.                     int_error("',' expected",c_token);
  1347.                 local_vals[i] = real(const_express(&a));
  1348.                 i++;
  1349.                 was_comma = FALSE;
  1350.             }
  1351.         }
  1352.  
  1353.         if (local_vals[0] < 0 || local_vals[0] > 180)
  1354.             int_error("rot_x must be in [0:180] degrees range; view unchanged",
  1355.                   c_token);
  1356.         if (local_vals[1] < 0 || local_vals[1] > 360)
  1357.             int_error("rot_z must be in [0:360] degrees range; view unchanged",
  1358.                   c_token);
  1359.         if (local_vals[2] < 1e-6)
  1360.             int_error("scale must be > 0; view unchanged", c_token);
  1361.         if (local_vals[3] < 1e-6)
  1362.             int_error("zscale must be > 0; view unchanged", c_token);
  1363.  
  1364.         surface_rot_x = local_vals[0];
  1365.         surface_rot_z = local_vals[1];
  1366.         surface_scale = local_vals[2];
  1367.         surface_zscale = local_vals[3];
  1368.     }
  1369.     else if (almost_equals(c_token,"vr$ange")) {
  1370.          TBOOLEAN changed;
  1371.         c_token++;
  1372.         if (!equals(c_token,"["))
  1373.             int_error("expecting '['",c_token);
  1374.         c_token++;
  1375.         changed = load_range(&vmin,&vmax);
  1376.         if (!equals(c_token,"]"))
  1377.           int_error("expecting ']'",c_token);
  1378.         c_token++;
  1379.         if (changed)
  1380.           autoscale_v = FALSE;
  1381.     }
  1382.     else if (almost_equals(c_token,"xr$ange")) {
  1383.          TBOOLEAN changed;
  1384.         c_token++;
  1385.         if (!equals(c_token,"["))
  1386.             int_error("expecting '['",c_token);
  1387.         c_token++;
  1388.         changed = load_range(&xmin,&xmax);
  1389.         if (!equals(c_token,"]"))
  1390.           int_error("expecting ']'",c_token);
  1391.         c_token++;
  1392.         if (changed)
  1393.           autoscale_x = FALSE;
  1394.     }
  1395.     else if (almost_equals(c_token,"yr$ange")) {
  1396.          TBOOLEAN changed;
  1397.         c_token++;
  1398.         if (!equals(c_token,"["))
  1399.             int_error("expecting '['",c_token);
  1400.         c_token++;
  1401.         changed = load_range(&ymin,&ymax);
  1402.         if (!equals(c_token,"]"))
  1403.           int_error("expecting ']'",c_token);
  1404.         c_token++;
  1405.         if (changed)
  1406.           autoscale_y = FALSE;
  1407.     }
  1408.     else if (almost_equals(c_token,"zr$ange")) {
  1409.          TBOOLEAN changed;
  1410.         c_token++;
  1411.         if (!equals(c_token,"["))
  1412.             int_error("expecting '['",c_token);
  1413.         c_token++;
  1414.         changed = load_range(&zmin,&zmax);
  1415.         if (!equals(c_token,"]"))
  1416.           int_error("expecting ']'",c_token);
  1417.         c_token++;
  1418.         if (changed)
  1419.           autoscale_z = FALSE;
  1420.     }
  1421.     else if (almost_equals(c_token,"z$ero")) {
  1422.         struct value a;
  1423.         c_token++;
  1424.         zero = magnitude(const_express(&a));
  1425.     }
  1426.     else
  1427.         return(FALSE);    /* no command match */
  1428.     return(TRUE);
  1429. }
  1430. #endif
  1431.  
  1432. #ifdef THINK_C_1
  1433. /*********** Support functions for set_command ***********/
  1434.  
  1435. /* process a 'set {x/y/z}label command */
  1436. /* set {x/y/z}label {label_text} {x}{,y} */
  1437. static void set_xyzlabel(str,xpos,ypos)
  1438. char *str;
  1439. int *xpos,*ypos;
  1440. {
  1441.     c_token++;
  1442.     if (END_OF_COMMAND) {    /* no label specified */
  1443.         str[0] = '\0';
  1444.     } else {
  1445.         if (isstring(c_token)) {
  1446.             /* We have string specified - grab it. */
  1447.             quotel_str(str,c_token);
  1448.             c_token++;
  1449.         }
  1450.         if (!END_OF_COMMAND) {
  1451.             struct value a;
  1452.  
  1453.             /* We have x,y offsets specified */
  1454.             if (!equals(c_token,","))
  1455.                 *xpos = (int)real(const_express(&a));
  1456.             if (!END_OF_COMMAND && equals(c_token,",")) {
  1457.                 c_token++;
  1458.                 *ypos = (int)real(const_express(&a));
  1459.             }
  1460.         }
  1461.     }
  1462. }
  1463. #endif
  1464.  
  1465. #ifdef THINK_C_1
  1466. /* process a 'set label' command */
  1467. /* set label {tag} {label_text} {at x,y} {pos} */
  1468. static void
  1469. set_label()
  1470. {
  1471.     struct value a;
  1472.     struct text_label *this_label = NULL;
  1473.     struct text_label *new_label = NULL;
  1474.     struct text_label *prev_label = NULL;
  1475.     double x, y, z;
  1476.     char text[MAX_LINE_LEN+1];
  1477.     enum JUSTIFY just;
  1478.     int tag;
  1479.     TBOOLEAN set_text, set_position, set_just;
  1480.  
  1481.     /* get tag */
  1482.     if (!END_OF_COMMAND 
  1483.        && !isstring(c_token) 
  1484.        && !equals(c_token, "at")
  1485.        && !equals(c_token, "left")
  1486.        && !equals(c_token, "center")
  1487.        && !equals(c_token, "centre")
  1488.        && !equals(c_token, "right")) {
  1489.        /* must be a tag expression! */
  1490.        tag = (int)real(const_express(&a));
  1491.        if (tag <= 0)
  1492.         int_error("tag must be > zero", c_token);
  1493.     } else
  1494.      tag = assign_label_tag(); /* default next tag */
  1495.      
  1496.     /* get text */
  1497.     if (!END_OF_COMMAND && isstring(c_token)) {
  1498.        /* get text */
  1499.        quotel_str(text, c_token);
  1500.        c_token++;
  1501.        set_text = TRUE;
  1502.     } else {
  1503.        text[0] = '\0';        /* default no text */
  1504.        set_text = FALSE;
  1505.     }
  1506.      
  1507.     /* get justification - what the heck, let him put it here */
  1508.     if (!END_OF_COMMAND && !equals(c_token, "at")) {
  1509.        if (almost_equals(c_token,"l$eft")) {
  1510.           just = LEFT;
  1511.        }
  1512.        else if (almost_equals(c_token,"c$entre")
  1513.               || almost_equals(c_token,"c$enter")) {
  1514.           just = CENTRE;
  1515.        }
  1516.        else if (almost_equals(c_token,"r$ight")) {
  1517.           just = RIGHT;
  1518.        }
  1519.        else
  1520.         int_error("bad syntax in set label", c_token);
  1521.        c_token++;
  1522.        set_just = TRUE;
  1523.     } else {
  1524.        just = LEFT;            /* default left justified */
  1525.        set_just = FALSE;
  1526.     } 
  1527.  
  1528.     /* get position */
  1529.     if (!END_OF_COMMAND && equals(c_token, "at")) {
  1530.        c_token++;
  1531.        if (END_OF_COMMAND)
  1532.         int_error("coordinates expected", c_token);
  1533.        /* get coordinates */
  1534.        x = real(const_express(&a));
  1535.        if (!equals(c_token,","))
  1536.         int_error("',' expected",c_token);
  1537.        c_token++;
  1538.        y = real(const_express(&a));
  1539.        if (equals(c_token,",")) {
  1540.         c_token++;
  1541.         z = real(const_express(&a));
  1542.        }
  1543.        else
  1544.             z = 0;
  1545.        set_position = TRUE;
  1546.     } else {
  1547.        x = y = z = 0;            /* default at origin */
  1548.        set_position = FALSE;
  1549.     }
  1550.  
  1551.     /* get justification */
  1552.     if (!END_OF_COMMAND) {
  1553.        if (set_just)
  1554.         int_error("only one justification is allowed", c_token);
  1555.        if (almost_equals(c_token,"l$eft")) {
  1556.           just = LEFT;
  1557.        }
  1558.        else if (almost_equals(c_token,"c$entre")
  1559.               || almost_equals(c_token,"c$enter")) {
  1560.           just = CENTRE;
  1561.        }
  1562.        else if (almost_equals(c_token,"r$ight")) {
  1563.           just = RIGHT;
  1564.        }
  1565.        else
  1566.         int_error("bad syntax in set label", c_token);
  1567.        c_token++;
  1568.        set_just = TRUE;
  1569.     } 
  1570.  
  1571.     if (!END_OF_COMMAND)
  1572.      int_error("extraenous or out-of-order arguments in set label", c_token);
  1573.  
  1574.     /* OK! add label */
  1575.     if (first_label != NULL) { /* skip to last label */
  1576.        for (this_label = first_label; this_label != NULL ; 
  1577.            prev_label = this_label, this_label = this_label->next)
  1578.         /* is this the label we want? */
  1579.         if (tag <= this_label->tag)
  1580.           break;
  1581.     }
  1582.     if (this_label != NULL && tag == this_label->tag) {
  1583.        /* changing the label */
  1584.        if (set_position) {
  1585.           this_label->x = x;
  1586.           this_label->y = y;
  1587.           this_label->z = z;
  1588.        }
  1589.        if (set_text)
  1590.         (void) strcpy(this_label->text, text);
  1591.        if (set_just)
  1592.         this_label->pos = just;
  1593.     } else {
  1594.        /* adding the label */
  1595.        new_label = (struct text_label *) 
  1596.         alloc ( (unsigned long) sizeof(struct text_label), "label");
  1597.        if (prev_label != NULL)
  1598.         prev_label->next = new_label; /* add it to end of list */
  1599.        else 
  1600.         first_label = new_label; /* make it start of list */
  1601.        new_label->tag = tag;
  1602.        new_label->next = this_label;
  1603.        new_label->x = x;
  1604.        new_label->y = y;
  1605.        new_label->z = z;
  1606.        (void) strcpy(new_label->text, text);
  1607.        new_label->pos = just;
  1608.     }
  1609. }
  1610. #endif
  1611.  
  1612. #ifdef THINK_C_1
  1613. /* process 'set nolabel' command */
  1614. /* set nolabel {tag} */
  1615. static void
  1616. set_nolabel()
  1617. {
  1618.     struct value a;
  1619.     struct text_label *this_label;
  1620.     struct text_label *prev_label; 
  1621.     int tag;
  1622.  
  1623.     if (END_OF_COMMAND) {
  1624.        /* delete all labels */
  1625.        while (first_label != NULL)
  1626.         delete_label((struct text_label *)NULL,first_label);
  1627.     }
  1628.     else {
  1629.        /* get tag */
  1630.        tag = (int)real(const_express(&a));
  1631.        if (!END_OF_COMMAND)
  1632.         int_error("extraneous arguments to set nolabel", c_token);
  1633.        for (this_label = first_label, prev_label = NULL;
  1634.            this_label != NULL;
  1635.            prev_label = this_label, this_label = this_label->next) {
  1636.           if (this_label->tag == tag) {
  1637.              delete_label(prev_label,this_label);
  1638.              return;        /* exit, our job is done */
  1639.           }
  1640.        }
  1641.        int_error("label not found", c_token);
  1642.     }
  1643. }
  1644. #endif
  1645.  
  1646. #ifdef THINK_C_1
  1647. /* assign a new label tag */
  1648. /* labels are kept sorted by tag number, so this is easy */
  1649. static int                /* the lowest unassigned tag number */
  1650. assign_label_tag()
  1651. {
  1652.     struct text_label *this_label;
  1653.     int last = 0;            /* previous tag value */
  1654.  
  1655.     for (this_label = first_label; this_label != NULL;
  1656.         this_label = this_label->next)
  1657.      if (this_label->tag == last+1)
  1658.        last++;
  1659.      else
  1660.        break;
  1661.     
  1662.     return (last+1);
  1663. }
  1664. #endif
  1665.  
  1666. #ifdef THINK_C_1
  1667. /* delete label from linked list started by first_label.
  1668.  * called with pointers to the previous label (prev) and the 
  1669.  * label to delete (this).
  1670.  * If there is no previous label (the label to delete is
  1671.  * first_label) then call with prev = NULL.
  1672.  */
  1673. static void
  1674. delete_label(prev,this)
  1675.     struct text_label *prev, *this;
  1676. {
  1677.     if (this!=NULL)    {        /* there really is something to delete */
  1678.        if (prev!=NULL)        /* there is a previous label */
  1679.         prev->next = this->next; 
  1680.        else                /* this = first_label so change first_label */
  1681.         first_label = this->next;
  1682.        free((char *)this);
  1683.     }
  1684. }
  1685. #endif
  1686.  
  1687. #ifdef THINK_C_1
  1688. /* process a 'set arrow' command */
  1689. /* set arrow {tag} {from x,y} {to x,y} {{no}head} */
  1690. static void
  1691. set_arrow()
  1692. {
  1693.     struct value a;
  1694.     struct arrow_def *this_arrow = NULL;
  1695.     struct arrow_def *new_arrow = NULL;
  1696.     struct arrow_def *prev_arrow = NULL;
  1697.     double sx, sy, sz;
  1698.     double ex, ey, ez;
  1699.     int tag;
  1700.     TBOOLEAN set_start, set_end, head = 1;
  1701.  
  1702.     /* get tag */
  1703.     if (!END_OF_COMMAND 
  1704.        && !equals(c_token, "from")
  1705.        && !equals(c_token, "to")) {
  1706.        /* must be a tag expression! */
  1707.        tag = (int)real(const_express(&a));
  1708.        if (tag <= 0)
  1709.         int_error("tag must be > zero", c_token);
  1710.     } else
  1711.      tag = assign_arrow_tag(); /* default next tag */
  1712.      
  1713.     /* get start position */
  1714.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1715.        c_token++;
  1716.        if (END_OF_COMMAND)
  1717.         int_error("start coordinates expected", c_token);
  1718.        /* get coordinates */
  1719.        sx = real(const_express(&a));
  1720.        if (!equals(c_token,","))
  1721.         int_error("',' expected",c_token);
  1722.        c_token++;
  1723.        sy = real(const_express(&a));
  1724.        if (equals(c_token,",")) {
  1725.         c_token++;
  1726.         sz = real(const_express(&a));
  1727.        }
  1728.        else
  1729.            sz = 0;
  1730.        set_start = TRUE;
  1731.     } else {
  1732.        sx = sy = sz = 0;            /* default at origin */
  1733.        set_start = FALSE;
  1734.     }
  1735.  
  1736.     /* get end position */
  1737.     if (!END_OF_COMMAND && equals(c_token, "to")) {
  1738.        c_token++;
  1739.        if (END_OF_COMMAND)
  1740.         int_error("end coordinates expected", c_token);
  1741.        /* get coordinates */
  1742.        ex = real(const_express(&a));
  1743.        if (!equals(c_token,","))
  1744.         int_error("',' expected",c_token);
  1745.        c_token++;
  1746.        ey = real(const_express(&a));
  1747.        if (equals(c_token,",")) {
  1748.         c_token++;
  1749.         ez = real(const_express(&a));
  1750.        }
  1751.        else
  1752.         ez = 0;
  1753.        set_end = TRUE;
  1754.     } else {
  1755.        ex = ey = ez = 0;            /* default at origin */
  1756.        set_end = FALSE;
  1757.     }
  1758.  
  1759.     /* get start position - what the heck, either order is ok */
  1760.     if (!END_OF_COMMAND && equals(c_token, "from")) {
  1761.        if (set_start)
  1762.         int_error("only one 'from' is allowed", c_token);
  1763.        c_token++;
  1764.        if (END_OF_COMMAND)
  1765.         int_error("start coordinates expected", c_token);
  1766.        /* get coordinates */
  1767.        sx = real(const_express(&a));
  1768.        if (!equals(c_token,","))
  1769.         int_error("',' expected",c_token);
  1770.        c_token++;
  1771.        sy = real(const_express(&a));
  1772.        if (equals(c_token,",")) {
  1773.         c_token++;
  1774.         sz = real(const_express(&a));
  1775.        }
  1776.        else
  1777.            sz = 0;
  1778.        set_start = TRUE;
  1779.     }
  1780.  
  1781.     if (!END_OF_COMMAND && equals(c_token, "nohead")) {
  1782.        c_token++;
  1783.            head = 0;
  1784.     }
  1785.  
  1786.     if (!END_OF_COMMAND && equals(c_token, "head")) {
  1787.        c_token++;
  1788.            head = 1;
  1789.     }
  1790.  
  1791.     if (!END_OF_COMMAND)
  1792.      int_error("extraneous or out-of-order arguments in set arrow", c_token);
  1793.  
  1794.     /* OK! add arrow */
  1795.     if (first_arrow != NULL) { /* skip to last arrow */
  1796.        for (this_arrow = first_arrow; this_arrow != NULL ; 
  1797.            prev_arrow = this_arrow, this_arrow = this_arrow->next)
  1798.         /* is this the arrow we want? */
  1799.         if (tag <= this_arrow->tag)
  1800.           break;
  1801.     }
  1802.     if (this_arrow != NULL && tag == this_arrow->tag) {
  1803.        /* changing the arrow */
  1804.        if (set_start) {
  1805.           this_arrow->sx = sx;
  1806.           this_arrow->sy = sy;
  1807.           this_arrow->sz = sz;
  1808.        }
  1809.        if (set_end) {
  1810.           this_arrow->ex = ex;
  1811.           this_arrow->ey = ey;
  1812.           this_arrow->ez = ez;
  1813.        }
  1814.        this_arrow->head = head;
  1815.     } else {
  1816.        /* adding the arrow */
  1817.        new_arrow = (struct arrow_def *) 
  1818.         alloc ( (unsigned long) sizeof(struct arrow_def), "arrow");
  1819.        if (prev_arrow != NULL)
  1820.         prev_arrow->next = new_arrow; /* add it to end of list */
  1821.        else 
  1822.         first_arrow = new_arrow; /* make it start of list */
  1823.        new_arrow->tag = tag;
  1824.        new_arrow->next = this_arrow;
  1825.        new_arrow->sx = sx;
  1826.        new_arrow->sy = sy;
  1827.        new_arrow->sz = sz;
  1828.        new_arrow->ex = ex;
  1829.        new_arrow->ey = ey;
  1830.        new_arrow->ez = ez;
  1831.        new_arrow->head = head;
  1832.     }
  1833. }
  1834. #endif
  1835.  
  1836. #ifdef THINK_C_1
  1837. /* process 'set noarrow' command */
  1838. /* set noarrow {tag} */
  1839. static void
  1840. set_noarrow()
  1841. {
  1842.     struct value a;
  1843.     struct arrow_def *this_arrow;
  1844.     struct arrow_def *prev_arrow; 
  1845.     int tag;
  1846.  
  1847.     if (END_OF_COMMAND) {
  1848.        /* delete all arrows */
  1849.        while (first_arrow != NULL)
  1850.         delete_arrow((struct arrow_def *)NULL,first_arrow);
  1851.     }
  1852.     else {
  1853.        /* get tag */
  1854.        tag = (int)real(const_express(&a));
  1855.        if (!END_OF_COMMAND)
  1856.         int_error("extraneous arguments to set noarrow", c_token);
  1857.        for (this_arrow = first_arrow, prev_arrow = NULL;
  1858.            this_arrow != NULL;
  1859.            prev_arrow = this_arrow, this_arrow = this_arrow->next) {
  1860.           if (this_arrow->tag == tag) {
  1861.              delete_arrow(prev_arrow,this_arrow);
  1862.              return;        /* exit, our job is done */
  1863.           }
  1864.        }
  1865.        int_error("arrow not found", c_token);
  1866.     }
  1867. }
  1868. #endif
  1869.  
  1870. #ifdef THINK_C_1
  1871. /* assign a new arrow tag */
  1872. /* arrows are kept sorted by tag number, so this is easy */
  1873. static int                /* the lowest unassigned tag number */
  1874. assign_arrow_tag()
  1875. {
  1876.     struct arrow_def *this_arrow;
  1877.     int last = 0;            /* previous tag value */
  1878.  
  1879.     for (this_arrow = first_arrow; this_arrow != NULL;
  1880.         this_arrow = this_arrow->next)
  1881.      if (this_arrow->tag == last+1)
  1882.        last++;
  1883.      else
  1884.        break;
  1885.  
  1886.     return (last+1);
  1887. }
  1888. #endif
  1889.  
  1890. #ifdef THINK_C_1
  1891. /* delete arrow from linked list started by first_arrow.
  1892.  * called with pointers to the previous arrow (prev) and the 
  1893.  * arrow to delete (this).
  1894.  * If there is no previous arrow (the arrow to delete is
  1895.  * first_arrow) then call with prev = NULL.
  1896.  */
  1897. static void
  1898. delete_arrow(prev,this)
  1899.     struct arrow_def *prev, *this;
  1900. {
  1901.     if (this!=NULL)    {        /* there really is something to delete */
  1902.        if (prev!=NULL)        /* there is a previous arrow */
  1903.         prev->next = this->next; 
  1904.        else                /* this = first_arrow so change first_arrow */
  1905.         first_arrow = this->next;
  1906.        free((char *)this);
  1907.     }
  1908. }
  1909. #endif
  1910.  
  1911. #ifdef THINK_C_1
  1912. enum PLOT_STYLE            /* not static; used by command.c */
  1913. get_style()
  1914. {
  1915. register enum PLOT_STYLE ps;
  1916.  
  1917.     c_token++;
  1918.     if (almost_equals(c_token,"l$ines"))
  1919.         ps = LINES;
  1920.     else if (almost_equals(c_token,"i$mpulses"))
  1921.         ps = IMPULSES;
  1922.     else if (almost_equals(c_token,"p$oints"))
  1923.         ps = POINTSTYLE;
  1924.     else if (almost_equals(c_token,"linesp$oints"))
  1925.         ps = LINESPOINTS;
  1926.     else if (almost_equals(c_token,"d$ots"))
  1927.         ps = DOTS;
  1928.     else if (almost_equals(c_token,"e$rrorbars"))
  1929.         ps = ERRORBARS;
  1930.     else if (almost_equals(c_token,"b$oxes"))
  1931.         ps = BOXES;
  1932.     else if (almost_equals(c_token,"boxer$rorbars"))
  1933.         ps = BOXERROR;
  1934.     else if (almost_equals(c_token,"s$teps"))
  1935.         ps = STEPS;
  1936.     else
  1937.         int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses', \n\
  1938.         'errorbars', 'steps', 'boxes' or 'boxerrorbars'",c_token);
  1939.     c_token++;
  1940.     return(ps);
  1941. }
  1942. #endif
  1943.  
  1944. #ifdef THINK_C_1
  1945. /* For set [xy]tics... command*/
  1946. static void
  1947. load_tics(tdef)
  1948.     struct ticdef *tdef;    /* change this ticdef */
  1949. {
  1950.     if (equals(c_token,"(")) { /* set : TIC_USER */
  1951.        c_token++;
  1952.        load_tic_user(tdef);
  1953.     } else {                /* series : TIC_SERIES */
  1954.        load_tic_series(tdef);
  1955.     }
  1956. }
  1957. #endif
  1958.  
  1959. #ifdef THINK_C_1
  1960. /* load TIC_USER definition */
  1961. /* (tic[,tic]...)
  1962.  * where tic is ["string"] value
  1963.  * Left paren is already scanned off before entry.
  1964.  */
  1965. static void
  1966. load_tic_user(tdef)
  1967.     struct ticdef *tdef;
  1968. {
  1969.     struct ticmark *list = NULL; /* start of list */
  1970.     struct ticmark *last = NULL; /* end of list */
  1971.     struct ticmark *tic = NULL; /* new ticmark */
  1972.     char temp_string[MAX_LINE_LEN];
  1973.     struct value a;
  1974.  
  1975.     while (!END_OF_COMMAND) {
  1976.        /* parse a new ticmark */
  1977.        tic = (struct ticmark *)alloc((unsigned long)sizeof(struct ticmark), (char *)NULL);
  1978.        if (tic == (struct ticmark *)NULL) {
  1979.           free_marklist(list);
  1980.           int_error("out of memory for tic mark", c_token);
  1981.        }
  1982.  
  1983.        /* has a string with it? */
  1984.        if (isstring(c_token)) {
  1985.           quote_str(temp_string,c_token);
  1986.           tic->label = alloc((unsigned long)strlen(temp_string)+1, "tic label");
  1987.           (void) strcpy(tic->label, temp_string);
  1988.           c_token++;
  1989.        } else
  1990.         tic->label = NULL;
  1991.  
  1992.        /* in any case get the value */
  1993.        tic->position = real(const_express(&a));
  1994.        tic->next = NULL;
  1995.  
  1996.        /* append to list */
  1997.        if (list == NULL)
  1998.         last = list = tic;    /* new list */
  1999.        else {                /* append to list */
  2000.           last->next = tic;
  2001.           last = tic;
  2002.        }
  2003.  
  2004.        /* expect "," or ")" here */
  2005.        if (!END_OF_COMMAND && equals(c_token, ","))
  2006.         c_token++;        /* loop again */
  2007.        else
  2008.         break;            /* hopefully ")" */
  2009.     }
  2010.     
  2011.     if (END_OF_COMMAND || !equals(c_token, ")")) {
  2012.        free_marklist(list);
  2013.        int_error("expecting right parenthesis )", c_token);
  2014.     }
  2015.     c_token++;
  2016.     
  2017.     /* successful list */
  2018.     if (tdef->type == TIC_USER) {
  2019.        /* remove old list */
  2020.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  2021.        free_marklist(tdef->def.user);
  2022.        tdef->def.user = NULL;
  2023.     }
  2024.     tdef->type = TIC_USER;
  2025.     tdef->def.user = list;
  2026. }
  2027. #endif
  2028.  
  2029. #ifdef THINK_C_1
  2030. static void
  2031. free_marklist(list)
  2032.     struct ticmark *list;
  2033. {
  2034.     register struct ticmark *freeable;
  2035.  
  2036.     while (list != NULL) {
  2037.        freeable = list;
  2038.        list = list->next;
  2039.        if (freeable->label != NULL)
  2040.         free( (char *)freeable->label );
  2041.        free( (char *)freeable );
  2042.     }
  2043. }
  2044. #endif
  2045.  
  2046. #ifdef THINK_C_1
  2047. /* load TIC_SERIES definition */
  2048. /* start,incr[,end] */
  2049. static void
  2050. load_tic_series(tdef)
  2051.     struct ticdef *tdef;
  2052. {
  2053.     double start, incr, end;
  2054.     struct value a;
  2055.     int incr_token;
  2056.  
  2057.     start = real(const_express(&a));
  2058.     if (!equals(c_token, ","))
  2059.      int_error("expecting comma to separate start,incr", c_token);
  2060.     c_token++;
  2061.  
  2062.     incr_token = c_token;
  2063.     incr = real(const_express(&a));
  2064.  
  2065.     if (END_OF_COMMAND)
  2066.      end = VERYLARGE;
  2067.     else {
  2068.        if (!equals(c_token, ","))
  2069.         int_error("expecting comma to separate incr,end", c_token);
  2070.        c_token++;
  2071.  
  2072.        end = real(const_express(&a));
  2073.     }
  2074.     if (!END_OF_COMMAND)
  2075.      int_error("tic series is defined by start,increment[,end]", 
  2076.              c_token);
  2077.     
  2078.     if (start < end && incr <= 0)
  2079.      int_error("increment must be positive", incr_token);
  2080.     if (start > end && incr >= 0)
  2081.      int_error("increment must be negative", incr_token);
  2082.     if (start > end) {
  2083.        /* put in order */
  2084.         double numtics;
  2085.         numtics = floor( (end*(1+SIGNIF) - start)/incr );
  2086.         end = start;
  2087.         start = end + numtics*incr;
  2088.         incr = -incr;
  2089. /*
  2090.        double temp = start;
  2091.        start = end;
  2092.        end = temp;
  2093.        incr = -incr;
  2094.  */
  2095.     }
  2096.  
  2097.     if (tdef->type == TIC_USER) {
  2098.        /* remove old list */
  2099.         /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  2100.        free_marklist(tdef->def.user);
  2101.        tdef->def.user = NULL;
  2102.     }
  2103.     tdef->type = TIC_SERIES;
  2104.     tdef->def.series.start = start;
  2105.     tdef->def.series.incr = incr;
  2106.     tdef->def.series.end = end;
  2107. }
  2108. #endif
  2109.  
  2110. #ifdef THINK_C_1
  2111. static void
  2112. load_offsets (a, b, c, d)
  2113. double *a,*b, *c, *d;
  2114. {
  2115. struct value t;
  2116.  
  2117.     *a = real (const_express(&t));  /* loff value */
  2118.     c_token++;
  2119.     if (equals(c_token,","))
  2120.         c_token++;
  2121.     if (END_OF_COMMAND) 
  2122.         return;
  2123.  
  2124.     *b = real (const_express(&t));  /* roff value */
  2125.     c_token++;
  2126.     if (equals(c_token,","))
  2127.         c_token++;
  2128.     if (END_OF_COMMAND) 
  2129.         return;
  2130.  
  2131.     *c = real (const_express(&t));  /* toff value */
  2132.     c_token++;
  2133.     if (equals(c_token,","))
  2134.         c_token++;
  2135.     if (END_OF_COMMAND) 
  2136.         return;
  2137.  
  2138.     *d = real (const_express(&t));  /* boff value */
  2139.     c_token++;
  2140. }
  2141. #endif
  2142.  
  2143. #ifdef THINK_C_1
  2144. TBOOLEAN                    /* TRUE if a or b were changed */
  2145. load_range(a,b)            /* also used by command.c */
  2146. double *a,*b;
  2147. {
  2148. struct value t;
  2149. TBOOLEAN changed = FALSE;
  2150.  
  2151.     if (equals(c_token,"]"))
  2152.         return(FALSE);
  2153.     if (END_OF_COMMAND) {
  2154.         int_error("starting range value or ':' or 'to' expected",c_token);
  2155.     } else if (!equals(c_token,"to") && !equals(c_token,":"))  {
  2156.         *a = real(const_express(&t));
  2157.         changed = TRUE;
  2158.     }    
  2159.     if (!equals(c_token,"to") && !equals(c_token,":"))
  2160.         int_error("':' or keyword 'to' expected",c_token);
  2161.     c_token++;
  2162.     if (!equals(c_token,"]")) {
  2163.         *b = real(const_express(&t));
  2164.         changed = TRUE;
  2165.      }
  2166.      return(changed);
  2167. }
  2168. #endif
  2169.  
  2170. #ifdef THINK_C_2
  2171. /******* The 'show' command *******/
  2172. void
  2173. show_command()
  2174. {
  2175.     static char GPFAR showmess[] = 
  2176.     "valid show options:  'action_table', 'all', 'angles', 'arrow', \n\
  2177.     'autoscale', 'border', 'boxwidth', 'clip', 'contour', 'data', \n\
  2178.     'dgrid3d', 'dummy', 'format', 'function', 'grid', 'hidden', 'key', \n\
  2179.     'label', 'logscale', 'mapping',  'offsets', 'output', 'plot', \n\
  2180.     'parametric', 'polar', 'rrange', 'samples', 'isosamples', 'view', \n\
  2181.     'size', 'terminal', 'tics', 'ticslevel', 'time', 'title', 'trange', \n\
  2182.     'urange', 'vrange', 'variables', 'version', \n\
  2183.     'xlabel', 'xrange', '{no}xtics', 'xmtics', 'xdtics', '{no}xzeroaxis',\n\
  2184.     'ylabel', 'yrange', '{no}ytics', 'ymtics', 'ydtics', '{no}yzeroaxis',\n\
  2185.      'zero', '{no}zeroaxis', 'zlabel', 'zrange', '{no}ztics',\n\
  2186.      'zmtics', 'zdtics'";
  2187.  
  2188.     c_token++;
  2189.  
  2190.     if (!show_one() && !show_two())
  2191.     int_error(showmess, c_token);
  2192.     screen_ok = FALSE;
  2193.     (void) putc('\n',stderr);
  2194. }
  2195. #endif
  2196.  
  2197. #ifdef THINK_C_2
  2198. /* return TRUE if a command match, FALSE if not */
  2199. static TBOOLEAN
  2200. show_one()
  2201. {
  2202.     if (almost_equals(c_token,"ac$tion_table") ||
  2203.              equals(c_token,"at") ) {
  2204.         c_token++; 
  2205.         show_at();
  2206.         c_token++;
  2207.     }
  2208.     else if (almost_equals(c_token,"ar$row")) {
  2209.         struct value a;
  2210.         int tag = 0;
  2211.  
  2212.         c_token++;
  2213.         if (!END_OF_COMMAND) {
  2214.            tag = (int)real(const_express(&a));
  2215.            if (tag <= 0)
  2216.             int_error("tag must be > zero", c_token);
  2217.         }
  2218.  
  2219.         (void) putc('\n',stderr);
  2220.         show_arrow(tag);
  2221.     }
  2222.     else if (almost_equals(c_token,"au$toscale")) {
  2223.         (void) putc('\n',stderr);
  2224.         show_autoscale();
  2225.         c_token++;
  2226.     }
  2227.     else if (almost_equals(c_token,"bor$der")) {
  2228.         (void) putc('\n',stderr);
  2229.         show_border();
  2230.         c_token++;
  2231.     }
  2232.     else if (almost_equals(c_token,"box$width")) {
  2233.         (void) putc('\n',stderr);
  2234.         show_boxwidth();
  2235.         c_token++;
  2236.     }
  2237.     else if (almost_equals(c_token,"c$lip")) {
  2238.         (void) putc('\n',stderr);
  2239.         show_clip();
  2240.         c_token++;
  2241.     }
  2242.     else if (almost_equals(c_token,"ma$pping")) {
  2243.         (void) putc('\n',stderr);
  2244.         show_mapping();
  2245.         c_token++;
  2246.     }
  2247.     else if (almost_equals(c_token,"co$ntour")) {
  2248.         (void) putc('\n',stderr);
  2249.         show_contour();
  2250.         c_token++;
  2251.     }
  2252.     else if (almost_equals(c_token,"da$ta")) {
  2253.         c_token++;
  2254.         if (!almost_equals(c_token,"s$tyle"))
  2255.             int_error("expecting keyword 'style'",c_token);
  2256.         (void) putc('\n',stderr);
  2257.         show_style("data",data_style);
  2258.         c_token++;
  2259.     }
  2260.     else if (almost_equals(c_token,"dg$rid3d")) {
  2261.         (void) putc('\n',stderr);
  2262.         show_dgrid3d();
  2263.         c_token++;
  2264.     }
  2265.     else if (almost_equals(c_token,"du$mmy")) {
  2266.           (void) fprintf(stderr,"\n\tdummy variables are \"%s\" and \"%s\"\n",
  2267.                         dummy_var[0], dummy_var[1]);
  2268.         c_token++;
  2269.     }
  2270.     else if (almost_equals(c_token,"fo$rmat")) {
  2271.         show_format();
  2272.         c_token++;
  2273.     }
  2274.     else if (almost_equals(c_token,"fu$nctions")) {
  2275.         c_token++;
  2276.         if (almost_equals(c_token,"s$tyle"))  {
  2277.             (void) putc('\n',stderr);
  2278.             show_style("functions",func_style);
  2279.             c_token++;
  2280.         }
  2281.         else
  2282.             show_functions();
  2283.     }
  2284.     else if (almost_equals(c_token,"lo$gscale")) {
  2285.         (void) putc('\n',stderr);
  2286.         show_logscale();
  2287.         c_token++;
  2288.     }
  2289.     else if (almost_equals(c_token,"of$fsets")) {
  2290.         (void) putc('\n',stderr);
  2291.         show_offsets();
  2292.         c_token++;
  2293.     }
  2294.     else if (almost_equals(c_token,"o$utput")) {
  2295.         (void) putc('\n',stderr);
  2296.         show_output();
  2297.         c_token++;
  2298.     }
  2299.     else if (almost_equals(c_token,"tit$le")) {
  2300.         (void) putc('\n',stderr);
  2301.         show_title();
  2302.         c_token++;
  2303.     }
  2304.     else if (almost_equals(c_token,"xl$abel")) {
  2305.         (void) putc('\n',stderr);
  2306.         show_xlabel();
  2307.         c_token++;
  2308.     }
  2309.     else if (almost_equals(c_token,"yl$abel")) {
  2310.         (void) putc('\n',stderr);
  2311.         show_ylabel();
  2312.         c_token++;
  2313.     }
  2314.     else if (almost_equals(c_token,"zl$abel")) {
  2315.         (void) putc('\n',stderr);
  2316.         show_zlabel();
  2317.         c_token++;
  2318.     }
  2319.     else if (almost_equals(c_token,"xzero$axis")) {
  2320.         (void) putc('\n',stderr);
  2321.         show_xzeroaxis();
  2322.         c_token++;
  2323.     }
  2324.     else if (almost_equals(c_token,"yzero$axis")) {
  2325.         (void) putc('\n',stderr);
  2326.         show_yzeroaxis();
  2327.         c_token++;
  2328.     }
  2329.     else if (almost_equals(c_token,"zeroa$xis")) {
  2330.         (void) putc('\n',stderr);
  2331.         show_xzeroaxis();
  2332.         show_yzeroaxis();
  2333.         c_token++;
  2334.     }
  2335.     else if (almost_equals(c_token,"la$bel")) {
  2336.         struct value a;
  2337.         int tag = 0;
  2338.  
  2339.         c_token++;
  2340.         if (!END_OF_COMMAND) {
  2341.            tag = (int)real(const_express(&a));
  2342.            if (tag <= 0)
  2343.             int_error("tag must be > zero", c_token);
  2344.         }
  2345.  
  2346.         (void) putc('\n',stderr);
  2347.         show_label(tag);
  2348.     }
  2349.     else if (almost_equals(c_token,"g$rid")) {
  2350.         (void) putc('\n',stderr);
  2351.         show_grid();
  2352.         c_token++;
  2353.     }
  2354.     else if (almost_equals(c_token,"k$ey")) {
  2355.         (void) putc('\n',stderr);
  2356.         show_key();
  2357.         c_token++;
  2358.     }
  2359.     else
  2360.         return (FALSE);
  2361.     return TRUE;
  2362. }
  2363. #endif
  2364.  
  2365. #ifdef THINK_C_2
  2366. /* return TRUE if a command match, FALSE if not */
  2367. static TBOOLEAN
  2368. show_two()
  2369. {
  2370.     if (almost_equals(c_token,"p$lot")) {
  2371.         (void) putc('\n',stderr);
  2372.         show_plot();
  2373.         c_token++;
  2374.     }
  2375.     else if (almost_equals(c_token,"par$ametric")) {
  2376.         (void) putc('\n',stderr);
  2377.         show_parametric();
  2378.         c_token++;
  2379.     }
  2380.     else if (almost_equals(c_token,"pol$ar")) {
  2381.         (void) putc('\n',stderr);
  2382.         show_polar();
  2383.         c_token++;
  2384.     }
  2385.     else if (almost_equals(c_token,"an$gles")) {
  2386.         (void) putc('\n',stderr);
  2387.         show_angles();
  2388.         c_token++;
  2389.     }
  2390.     else if (almost_equals(c_token,"ti$cs")) {
  2391.         (void) putc('\n',stderr);
  2392.         show_tics(TRUE,TRUE,TRUE);
  2393.         c_token++;
  2394.     }
  2395.     else if (almost_equals(c_token,"tim$e")) {
  2396.         (void) putc('\n',stderr);
  2397.         show_time();
  2398.         c_token++;
  2399.     }
  2400.     else if (almost_equals(c_token,"su$rface")) {
  2401.         (void) putc('\n',stderr);
  2402.         show_surface();
  2403.         c_token++;
  2404.     }
  2405.     else if (almost_equals(c_token,"hi$dden3d")) {
  2406.         (void) putc('\n',stderr);
  2407.         show_hidden3d();
  2408.         c_token++;
  2409.     }
  2410.      else if (almost_equals(c_token,"cla$bel")) {
  2411.          (void) putc('\n',stderr);
  2412.          show_label_contours();
  2413.          c_token++;
  2414.      }
  2415.     else if (almost_equals(c_token,"xti$cs")) {
  2416.         show_tics(TRUE,FALSE,FALSE);
  2417.         c_token++;
  2418.     }
  2419.     else if (almost_equals(c_token,"yti$cs")) {
  2420.         show_tics(FALSE,TRUE,FALSE);
  2421.         c_token++;
  2422.     }
  2423.     else if (almost_equals(c_token,"zti$cs")) {
  2424.         show_tics(FALSE,FALSE,TRUE);
  2425.         c_token++;
  2426.     }
  2427.     else if (almost_equals(c_token,"sa$mples")) {
  2428.         (void) putc('\n',stderr);
  2429.         show_samples();
  2430.         c_token++;
  2431.     }
  2432.     else if (almost_equals(c_token,"isosa$mples")) {
  2433.         (void) putc('\n',stderr);
  2434.         show_isosamples();
  2435.         c_token++;
  2436.     }
  2437.     else if (almost_equals(c_token,"si$ze")) {
  2438.         (void) putc('\n',stderr);
  2439.         show_size();
  2440.         c_token++;
  2441.     }
  2442.     else if (almost_equals(c_token,"t$erminal")) {
  2443.         (void) putc('\n',stderr);
  2444.         show_term();
  2445.         c_token++;
  2446.     }
  2447.     else if (almost_equals(c_token,"rr$ange")) {
  2448.         (void) putc('\n',stderr);
  2449.         show_range('r',rmin,rmax);
  2450.         c_token++;
  2451.     }
  2452.     else if (almost_equals(c_token,"tr$ange")) {
  2453.         (void) putc('\n',stderr);
  2454.         show_range('t',tmin,tmax);
  2455.         c_token++;
  2456.     }
  2457.     else if (almost_equals(c_token,"ur$ange")) {
  2458.         (void) putc('\n',stderr);
  2459.         show_range('u',umin,umax);
  2460.         c_token++;
  2461.     }
  2462.     else if (almost_equals(c_token,"vi$ew")) {
  2463.         (void) putc('\n',stderr);
  2464.         show_view();
  2465.         c_token++;
  2466.     }
  2467.     else if (almost_equals(c_token,"vr$ange")) {
  2468.         (void) putc('\n',stderr);
  2469.         show_range('v',vmin,vmax);
  2470.         c_token++;
  2471.     }
  2472.     else if (almost_equals(c_token,"v$ariables")) {
  2473.         show_variables();
  2474.         c_token++;
  2475.     }
  2476.     else if (almost_equals(c_token,"ve$rsion")) {
  2477.         show_version();
  2478.         c_token++;
  2479.     }
  2480.     else if (almost_equals(c_token,"xr$ange")) {
  2481.         (void) putc('\n',stderr);
  2482.         show_range('x',xmin,xmax);
  2483.         c_token++;
  2484.     }
  2485.     else if (almost_equals(c_token,"yr$ange")) {
  2486.         (void) putc('\n',stderr);
  2487.         show_range('y',ymin,ymax);
  2488.         c_token++;
  2489.     }
  2490.     else if (almost_equals(c_token,"zr$ange")) {
  2491.         (void) putc('\n',stderr);
  2492.         show_range('z',zmin,zmax);
  2493.         c_token++;
  2494.     }
  2495.     else if (almost_equals(c_token,"z$ero")) {
  2496.         (void) putc('\n',stderr);
  2497.         show_zero();
  2498.         c_token++;
  2499.     }
  2500.     else if (almost_equals(c_token,"a$ll")) {
  2501.         c_token++;
  2502.         show_version();
  2503.         show_autoscale();
  2504.         show_border();
  2505.         show_boxwidth();
  2506.         show_clip();
  2507.         show_contour();
  2508.         show_dgrid3d();
  2509.         show_mapping();
  2510.           (void) fprintf(stderr,"\tdummy variables are \"%s\" and \"%s\"\n",
  2511.                         dummy_var[0], dummy_var[1]);
  2512.         show_format();
  2513.         show_style("data",data_style);
  2514.         show_style("functions",func_style);
  2515.         show_grid();
  2516.         show_label(0);
  2517.         show_arrow(0);
  2518.         show_key();
  2519.         show_logscale();
  2520.         show_offsets();
  2521.         show_output();
  2522.         show_parametric();
  2523.         show_polar();
  2524.         show_angles();
  2525.         show_samples();
  2526.         show_isosamples();
  2527.         show_view();
  2528.         show_surface();
  2529. #ifndef LITE
  2530.         show_hidden3d();
  2531. #endif
  2532.         show_size();
  2533.         show_term();
  2534.         show_tics(TRUE,TRUE,TRUE);
  2535.         show_time();
  2536.         if (parametric)
  2537.             if (!is_3d_plot)
  2538.                 show_range('t',tmin,tmax);
  2539.             else {
  2540.                 show_range('u',umin,umax);
  2541.                 show_range('v',vmin,vmax);
  2542.             }
  2543.         if (polar)
  2544.           show_range('r',rmin,rmax);
  2545.         show_range('x',xmin,xmax);
  2546.         show_range('y',ymin,ymax);
  2547.         show_range('z',zmin,zmax);
  2548.         show_title();
  2549.         show_xlabel();
  2550.         show_ylabel();
  2551.         show_zlabel();
  2552.         show_zero();
  2553.         show_plot();
  2554.         show_variables();
  2555.         show_functions();
  2556.         c_token++;
  2557.     }
  2558.     else
  2559.         return (FALSE);
  2560.     return (TRUE);
  2561. }
  2562. #endif
  2563.  
  2564. #ifdef THINK_C_2
  2565. /*********** support functions for 'show'  **********/
  2566. static void
  2567. show_style(name,style)
  2568. char name[];
  2569. enum PLOT_STYLE style;
  2570. {
  2571.     fprintf(stderr,"\t%s are plotted with ",name);
  2572.     switch (style) {
  2573.         case LINES: fprintf(stderr,"lines\n"); break;
  2574.         case POINTSTYLE: fprintf(stderr,"points\n"); break;
  2575.         case IMPULSES: fprintf(stderr,"impulses\n"); break;
  2576.         case LINESPOINTS: fprintf(stderr,"linespoints\n"); break;
  2577.         case DOTS: fprintf(stderr,"dots\n"); break;
  2578.         case ERRORBARS: fprintf(stderr,"errorbars\n"); break;
  2579.         case BOXES: fprintf(stderr,"boxes\n"); break;
  2580.         case BOXERROR: fprintf(stderr,"boxerrorbars\n"); break;
  2581.         case STEPS: fprintf(stderr,"steps\n"); break;
  2582.     }
  2583. }
  2584. #endif
  2585.  
  2586. #ifdef THINK_C_2
  2587. static void
  2588. show_boxwidth()
  2589. {
  2590.     if (boxwidth<0.0)
  2591.         fprintf(stderr,"\tboxwidth is auto\n");
  2592.     else
  2593.         fprintf(stderr,"\tboxwidth is %g\n",boxwidth);
  2594. }
  2595. #endif
  2596.  
  2597. #ifdef THINK_C_2
  2598. static void
  2599. show_dgrid3d()
  2600. {
  2601.     if (dgrid3d)
  2602.         fprintf(stderr,"\tdata grid3d is enabled for mesh of size %dx%d, norm=%d\n",
  2603.             dgrid3d_row_fineness,
  2604.             dgrid3d_col_fineness,
  2605.             dgrid3d_norm_value);
  2606.     else
  2607.         fprintf(stderr,"\tdata grid3d is disabled\n");
  2608. }
  2609. #endif
  2610.  
  2611. #ifdef THINK_C_2
  2612. static void
  2613. show_range(name,min,max)
  2614. char name;
  2615. double min,max;
  2616. {
  2617.     fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
  2618. }
  2619. #endif
  2620.  
  2621. #ifdef THINK_C_2
  2622. static void
  2623. show_zero()
  2624. {
  2625.     fprintf(stderr,"\tzero is %g\n",zero);
  2626. }
  2627. #endif
  2628.  
  2629. #ifdef THINK_C_2
  2630. static void
  2631. show_offsets()
  2632. {
  2633.     fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",loff,roff,toff,boff);
  2634. }
  2635. #endif
  2636.  
  2637. #ifdef THINK_C_2
  2638. static void
  2639. show_border()
  2640. {
  2641.     fprintf(stderr,"\tborder is %sdrawn\n", draw_border ? "" : "not ");
  2642. }
  2643. #endif
  2644.  
  2645. #ifdef THINK_C_2
  2646. static void
  2647. show_output()
  2648. {
  2649.     fprintf(stderr,"\toutput is sent to %s\n",outstr);
  2650. }
  2651. #endif
  2652.  
  2653. #ifdef THINK_C_2
  2654. static void
  2655. show_samples()
  2656. {
  2657.     fprintf(stderr,"\tsampling rate is %d, %d\n",samples_1, samples_2);
  2658. }
  2659. #endif
  2660.  
  2661. #ifdef THINK_C_2
  2662. static void
  2663. show_isosamples()
  2664. {
  2665.     fprintf(stderr,"\tiso sampling rate is %d, %d\n",
  2666.         iso_samples_1, iso_samples_2);
  2667. }
  2668. #endif
  2669.  
  2670. #ifdef THINK_C_2
  2671. static void
  2672. show_surface()
  2673. {
  2674.     fprintf(stderr,"\tsurface is %sdrawn\n", draw_surface ? "" : "not ");
  2675. }
  2676. #endif
  2677.  
  2678. #ifdef THINK_C_2
  2679. static void
  2680. show_hidden3d()
  2681. {
  2682. #ifdef LITE
  2683.     printf(" Hidden Line Removal Not Supported in LITE version\n");
  2684. #else
  2685.     fprintf(stderr,"\thidden surface is %s\n", hidden3d ? "removed" : "drawn");
  2686. #endif /* LITE */
  2687. }
  2688. #endif
  2689.  
  2690. #ifdef THINK_C_2
  2691. static void
  2692. show_label_contours()
  2693. {
  2694.     fprintf(stderr,"\tcontour line types are %s\n", label_contours ? "varied & labeled" : "all the same");
  2695. }
  2696. #endif
  2697.  
  2698. #ifdef THINK_C_2
  2699. static void
  2700. show_view()
  2701. {
  2702.     fprintf(stderr,"\tview is %g rot_x, %g rot_z, %g scale, %g scale_z\n",
  2703.         surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  2704. }
  2705. #endif
  2706.  
  2707. #ifdef THINK_C_2
  2708. static void
  2709. show_size()
  2710. {
  2711.     fprintf(stderr,"\tsize is scaled by %g,%g\n",xsize,ysize);
  2712. }
  2713. #endif
  2714.  
  2715. #ifdef THINK_C_2
  2716. static void
  2717. show_title()
  2718. {
  2719.     fprintf(stderr,"\ttitle is \"%s\", offset at %d, %d\n",
  2720.         title,title_xoffset,title_yoffset);
  2721. }
  2722. #endif
  2723.  
  2724. #ifdef THINK_C_2
  2725. static void
  2726. show_xlabel()
  2727. {
  2728.     fprintf(stderr,"\txlabel is \"%s\", offset at %d, %d\n",
  2729.         xlabel,xlabel_xoffset,xlabel_yoffset);
  2730. }
  2731. #endif
  2732.  
  2733. #ifdef THINK_C_2
  2734. static void
  2735. show_ylabel()
  2736. {
  2737.     fprintf(stderr,"\tylabel is \"%s\", offset at %d, %d\n",
  2738.         ylabel,ylabel_xoffset,ylabel_yoffset);
  2739. }
  2740. #endif
  2741.  
  2742. #ifdef THINK_C_2
  2743. static void
  2744. show_zlabel()
  2745. {
  2746.     fprintf(stderr,"\tzlabel is \"%s\", offset at %d, %d\n",
  2747.         zlabel,zlabel_xoffset,zlabel_yoffset);
  2748. }
  2749. #endif
  2750.  
  2751. #ifdef THINK_C_2
  2752. static void
  2753. show_xzeroaxis()
  2754. {
  2755.     fprintf(stderr,"\txzeroaxis is %s\n",(xzeroaxis)? "ON" : "OFF");
  2756. }
  2757. #endif
  2758.  
  2759. #ifdef THINK_C_2
  2760. static void
  2761. show_yzeroaxis()
  2762. {
  2763.     fprintf(stderr,"\tyzeroaxis is %s\n",(yzeroaxis)? "ON" : "OFF");
  2764. }
  2765. #endif
  2766.  
  2767. #ifdef THINK_C_2
  2768. static void
  2769. show_label(tag)
  2770.     int tag;                /* 0 means show all */
  2771. {
  2772.     struct text_label *this_label;
  2773.     TBOOLEAN showed = FALSE;
  2774.  
  2775.     for (this_label = first_label; this_label != NULL;
  2776.         this_label = this_label->next) {
  2777.        if (tag == 0 || tag == this_label->tag) {
  2778.           showed = TRUE;
  2779.           fprintf(stderr,"\tlabel %d \"%s\" at %g,%g,%g ",
  2780.                 this_label->tag, this_label->text, 
  2781.                 this_label->x, this_label->y, this_label->z);
  2782.           switch(this_label->pos) {
  2783.              case LEFT : {
  2784.                 fprintf(stderr,"left");
  2785.                 break;
  2786.              }
  2787.              case CENTRE : {
  2788.                 fprintf(stderr,"centre");
  2789.                 break;
  2790.              }
  2791.              case RIGHT : {
  2792.                 fprintf(stderr,"right");
  2793.                 break;
  2794.              }
  2795.           }
  2796.           fputc('\n',stderr);
  2797.        }
  2798.     }
  2799.     if (tag > 0 && !showed)
  2800.      int_error("label not found", c_token);
  2801. }
  2802. #endif
  2803.  
  2804. #ifdef THINK_C_2
  2805. static void
  2806. show_arrow(tag)
  2807.     int tag;                /* 0 means show all */
  2808. {
  2809.     struct arrow_def *this_arrow;
  2810.     TBOOLEAN showed = FALSE;
  2811.  
  2812.     for (this_arrow = first_arrow; this_arrow != NULL;
  2813.         this_arrow = this_arrow->next) {
  2814.        if (tag == 0 || tag == this_arrow->tag) {
  2815.           showed = TRUE;
  2816.           fprintf(stderr,"\tarrow %d from %g,%g,%g to %g,%g,%g%s\n",
  2817.                 this_arrow->tag, 
  2818.                 this_arrow->sx, this_arrow->sy, this_arrow->sz,
  2819.                 this_arrow->ex, this_arrow->ey, this_arrow->ez,
  2820.                 this_arrow->head ? "" : " (nohead)");
  2821.        }
  2822.     }
  2823.     if (tag > 0 && !showed)
  2824.      int_error("arrow not found", c_token);
  2825. }
  2826. #endif
  2827.  
  2828. #ifdef THINK_C_2
  2829. static void
  2830. show_grid()
  2831. {
  2832.     fprintf(stderr,"\tgrid is %s\n",(grid)? "ON" : "OFF");
  2833. }
  2834. #endif
  2835.  
  2836. #ifdef THINK_C_2
  2837. static void
  2838. show_key()
  2839. {
  2840.     switch (key) {
  2841.         case -1 : 
  2842.             fprintf(stderr,"\tkey is ON\n");
  2843.             break;
  2844.         case 0 :
  2845.             fprintf(stderr,"\tkey is OFF\n");
  2846.             break;
  2847.         case 1 :
  2848.             fprintf(stderr,"\tkey is at %g,%g,%g\n",key_x,key_y,key_z);
  2849.             break;
  2850.     }
  2851. }
  2852. #endif
  2853.  
  2854. #ifdef THINK_C_2
  2855. static void
  2856. show_parametric()
  2857. {
  2858.     fprintf(stderr,"\tparametric is %s\n",(parametric)? "ON" : "OFF");
  2859. }
  2860. #endif
  2861.  
  2862. #ifdef THINK_C_2
  2863. static void
  2864. show_polar()
  2865. {
  2866.     fprintf(stderr,"\tpolar is %s\n",(polar)? "ON" : "OFF");
  2867. }
  2868. #endif
  2869.  
  2870. #ifdef THINK_C_2
  2871. static void
  2872. show_angles()
  2873. {
  2874.     fprintf(stderr,"\tAngles are in ");
  2875.     switch (angles_format) {
  2876.         case ANGLES_RADIANS:
  2877.             fprintf(stderr, "radians\n");
  2878.         break;
  2879.         case ANGLES_DEGREES:
  2880.             fprintf(stderr, "degrees\n");
  2881.         break;
  2882.     }
  2883. }
  2884. #endif
  2885.  
  2886. #ifdef THINK_C_2
  2887. static void
  2888. show_tics(showx, showy, showz)
  2889.     TBOOLEAN showx, showy, showz;
  2890. {
  2891.     fprintf(stderr,"\ttics are %s, ",(tic_in)? "IN" : "OUT");
  2892.     fprintf(stderr,"\tticslevel is %g\n",ticslevel);
  2893.  
  2894.     if (showx)
  2895.      show_ticdef(xtics, 'x', &xticdef);
  2896.     if (showy)
  2897.      show_ticdef(ytics, 'y', &yticdef);
  2898.     if (showz)
  2899.      show_ticdef(ztics, 'z', &zticdef);
  2900.     screen_ok = FALSE;
  2901. }
  2902. #endif
  2903.  
  2904. #ifdef THINK_C_2
  2905. /* called by show_tics */
  2906. static void
  2907. show_ticdef(tics, axis, tdef)
  2908.     TBOOLEAN tics;            /* xtics ytics or ztics */
  2909.     char axis;            /* 'x' 'y' or 'z' */
  2910.     struct ticdef *tdef;    /* xticdef yticdef or zticdef */
  2911. {
  2912.     register struct ticmark *t;
  2913.  
  2914.     fprintf(stderr, "\t%c-axis tic labelling is ", axis);
  2915.     if (!tics) {
  2916.        fprintf(stderr, "OFF\n");
  2917.        return;
  2918.     }
  2919.  
  2920.     switch(tdef->type) {
  2921.        case TIC_COMPUTED: {
  2922.           fprintf(stderr, "computed automatically\n");
  2923.           break;
  2924.        }
  2925.         case TIC_MONTH: {
  2926.         fprintf(stderr, "Months computed automatically\n");
  2927.         break;
  2928.        }
  2929.         case TIC_DAY:{
  2930.         fprintf(stderr, "Days computed automatically\n");
  2931.         }
  2932.        case TIC_SERIES: {
  2933.           if (tdef->def.series.end == VERYLARGE)
  2934.             fprintf(stderr, "series from %g by %g\n", 
  2935.                   tdef->def.series.start, tdef->def.series.incr);
  2936.           else
  2937.             fprintf(stderr, "series from %g by %g until %g\n", 
  2938.                   tdef->def.series.start, tdef->def.series.incr, 
  2939.                   tdef->def.series.end);
  2940.           break;
  2941.        }
  2942.        case TIC_USER: {
  2943.           fprintf(stderr, "list (");
  2944.           for (t = tdef->def.user; t != NULL; t=t->next) {
  2945.              if (t->label)
  2946.                fprintf(stderr, "\"%s\" ", t->label);
  2947.              if (t->next)
  2948.                fprintf(stderr, "%g, ", t->position);
  2949.              else
  2950.                fprintf(stderr, "%g", t->position);
  2951.           }
  2952.           fprintf(stderr, ")\n");
  2953.           break;
  2954.        }
  2955.        default: {
  2956.           int_error("unknown ticdef type in show_ticdef()", NO_CARET);
  2957.           /* NOTREACHED */
  2958.        }
  2959.     }
  2960. }
  2961. #endif
  2962.  
  2963. #ifdef THINK_C_2
  2964. static void
  2965. show_time()
  2966. {
  2967.     fprintf(stderr,"\ttime is %s, offset at %d, %d\n",
  2968.         (timedate)? "ON" : "OFF",
  2969.         time_xoffset,time_yoffset);
  2970. }
  2971. #endif
  2972.  
  2973. #ifdef THINK_C_2
  2974. static void
  2975. show_term()
  2976. {
  2977.     fprintf(stderr,"\tterminal type is %s %s\n",
  2978.         term_tbl[term].name, term_options);
  2979. }
  2980. #endif
  2981.  
  2982. #ifdef THINK_C_2
  2983. static void
  2984. show_plot()
  2985. {
  2986.     fprintf(stderr,"\tlast plot command was: %s\n",replot_line);
  2987. }
  2988. #endif
  2989.  
  2990. #ifdef THINK_C_2
  2991. static void
  2992. show_autoscale()
  2993. {
  2994.     fprintf(stderr,"\tautoscaling is ");
  2995.     if (parametric)
  2996.         if (is_3d_plot)
  2997.             fprintf(stderr,"\tt: %s, ",(autoscale_t)? "ON" : "OFF");
  2998.         else
  2999.             fprintf(stderr,"\tu: %s, v: %s, ",
  3000.                         (autoscale_u)? "ON" : "OFF",
  3001.                         (autoscale_v)? "ON" : "OFF");
  3002.     else fprintf(stderr,"\t");
  3003.  
  3004.     if (polar) fprintf(stderr,"r: %s, ",(autoscale_r)? "ON" : "OFF");
  3005.     fprintf(stderr,"x: %s, ",(autoscale_x)? "ON" : "OFF");
  3006.     fprintf(stderr,"y: %s, ",(autoscale_y)? "ON" : "OFF");
  3007.     fprintf(stderr,"z: %s\n",(autoscale_z)? "ON" : "OFF");
  3008. }
  3009. #endif
  3010.  
  3011. #ifdef THINK_C_2
  3012. static void
  3013. show_clip()
  3014. {
  3015.     fprintf(stderr,"\tpoint clip is %s\n",(clip_points)? "ON" : "OFF");
  3016.  
  3017.     if (clip_lines1)
  3018.       fprintf(stderr,
  3019.          "\tdrawing and clipping lines between inrange and outrange points\n");
  3020.     else
  3021.       fprintf(stderr,
  3022.          "\tnot drawing lines between inrange and outrange points\n");
  3023.  
  3024.     if (clip_lines2)
  3025.       fprintf(stderr,
  3026.          "\tdrawing and clipping lines between two outrange points\n");
  3027.     else
  3028.       fprintf(stderr,
  3029.          "\tnot drawing lines between two outrange points\n");
  3030. }
  3031. #endif
  3032.  
  3033. #ifdef THINK_C_2
  3034. static void
  3035. show_mapping()
  3036. {
  3037.     fprintf(stderr,"\tmapping for 3-d data is ");
  3038.  
  3039.     switch (mapping3d) {
  3040.         case MAP3D_CARTESIAN:
  3041.             fprintf(stderr,"cartesian\n");
  3042.             break;
  3043.         case MAP3D_SPHERICAL:
  3044.             fprintf(stderr,"spherical\n");
  3045.             break;
  3046.         case MAP3D_CYLINDRICAL:
  3047.             fprintf(stderr,"cylindrical\n");
  3048.             break;
  3049.     }
  3050. }
  3051. #endif
  3052.  
  3053. #ifdef THINK_C_2
  3054. static void
  3055. show_contour()
  3056. {
  3057.     fprintf(stderr,"\tcontour for surfaces are %s",
  3058.         (draw_contour)? "drawn" : "not drawn\n");
  3059.  
  3060.     if (draw_contour) {
  3061.             fprintf(stderr, " in %d levels on ", contour_levels);
  3062.         switch (draw_contour) {
  3063.             case CONTOUR_BASE:
  3064.                 fprintf(stderr,"grid base\n");
  3065.                 break;
  3066.             case CONTOUR_SRF:
  3067.                 fprintf(stderr,"surface\n");
  3068.                 break;
  3069.             case CONTOUR_BOTH:
  3070.                 fprintf(stderr,"grid base and surface\n");
  3071.                 break;
  3072.         }
  3073.         switch (contour_kind) {
  3074.             case CONTOUR_KIND_LINEAR:
  3075.                 fprintf(stderr,"\t\tas linear segments\n");
  3076.                 break;
  3077.             case CONTOUR_KIND_CUBIC_SPL:
  3078.                 fprintf(stderr,"\t\tas cubic spline interpolation segments with %d pts\n",
  3079.                     contour_pts);
  3080.                 break;
  3081.             case CONTOUR_KIND_BSPLINE:
  3082.                 fprintf(stderr,"\t\tas bspline approximation segments of order %d with %d pts\n",
  3083.                     contour_order, contour_pts);
  3084.                 break;
  3085.         }
  3086.         switch (levels_kind) {
  3087.             int i;
  3088.             case LEVELS_AUTO:
  3089.                 fprintf(stderr,"\t\t%d automatic levels\n", contour_levels);
  3090.                 break;
  3091.             case LEVELS_DISCRETE:
  3092.                 fprintf(stderr,"\t\t%d discrete levels at ", contour_levels);
  3093.                         fprintf(stderr, "%g", levels_list[0]);
  3094.                 for(i = 1; i < contour_levels; i++)
  3095.                     fprintf(stderr,",%g ", levels_list[i]);
  3096.                 fprintf(stderr,"\n");
  3097.                 break;
  3098.             case LEVELS_INCREMENTAL:
  3099.                 fprintf(stderr,"\t\t%d incremental levels starting at %g, step %g, end %g\n",
  3100.                     contour_levels, levels_list[0], levels_list[1],
  3101.                     levels_list[0]+contour_levels*levels_list[1]);
  3102.                 break;
  3103.         }
  3104.         fprintf(stderr,"\t\tcontour line types are %s\n", label_contours ? "varied" : "all the same");
  3105.     }
  3106. }
  3107. #endif
  3108.  
  3109. #ifdef THINK_C_2
  3110. static void
  3111. show_format()
  3112. {
  3113.     fprintf(stderr, "\ttic format is x-axis: \"%s\", y-axis: \"%s\", z-axis: \"%s\"\n",
  3114.         xformat, yformat, zformat);
  3115. }
  3116. #endif
  3117.  
  3118. #ifdef THINK_C_2
  3119. static void
  3120. show_logscale()
  3121. {
  3122.     if (is_log_x) {
  3123.         fprintf(stderr,"\tlogscaling x (base %g)", base_log_x);
  3124.         if (is_log_y && is_log_z)
  3125.             fprintf(stderr,", y (base %g) and z (base %g)\n",
  3126.                 base_log_y, base_log_z);
  3127.         else if (is_log_y)
  3128.             fprintf(stderr," and y (base %g)\n", base_log_y);
  3129.         else if (is_log_z)
  3130.             fprintf(stderr," and z (base %g)\n", base_log_z);
  3131.         else
  3132.             fprintf(stderr," only\n");
  3133.     } else if (is_log_y) {
  3134.         fprintf(stderr,"\tlogscaling y (base %g)", base_log_y);
  3135.         if (is_log_z)
  3136.             fprintf(stderr," and z (base %g)\n", base_log_z);
  3137.         else
  3138.             fprintf(stderr," only\n");
  3139.     } else if (is_log_z) {
  3140.         fprintf(stderr,"\tlogscaling z (base %g) only\n", base_log_z);
  3141.     } else {
  3142.         fprintf(stderr,"\tno logscaling\n");
  3143.     }
  3144. }
  3145. #endif
  3146.  
  3147. #ifdef THINK_C_2
  3148. static void
  3149. show_variables()
  3150. {
  3151. register struct udvt_entry *udv = first_udv;
  3152. int len;
  3153.  
  3154.     fprintf(stderr,"\n\tVariables:\n");
  3155.     while (udv) {
  3156.          len = instring(udv->udv_name, ' ');
  3157.         fprintf(stderr,"\t%-*s ",len,udv->udv_name);
  3158.         if (udv->udv_undef)
  3159.             fputs("is undefined\n",stderr);
  3160.         else {
  3161.             fputs("= ",stderr);
  3162.             disp_value(stderr,&(udv->udv_value));
  3163.             (void) putc('\n',stderr);
  3164.         }
  3165.         udv = udv->next_udv;
  3166.     }
  3167. }
  3168. #endif
  3169.  
  3170. #ifdef THINK_C_2
  3171. char *authors[] = {"Thomas Williams","Colin Kelley"}; /* primary */
  3172. void                /* used by plot.c */
  3173. show_version()
  3174. {
  3175. extern char version[];
  3176. extern char patchlevel[];
  3177. extern char date[];
  3178. extern char copyright[];
  3179. extern char bug_email[];
  3180. extern char help_email[];
  3181. int x;
  3182. #ifdef THINK_C
  3183. time_t time(time_t *timer);
  3184. #else
  3185. long time();
  3186. #endif
  3187.  
  3188. #ifdef THINK_C
  3189.     x = time((time_t *)NULL) & 1;
  3190. #else
  3191.     x = time((long *)NULL) & 1;
  3192. #endif
  3193.     fprintf(stderr,"\n\t%s\n\t%sversion %s\n",
  3194.         PROGRAM, OS, version); 
  3195.     fprintf(stderr,"\tpatchlevel %s\n",patchlevel);
  3196.      fprintf(stderr, "\tlast modified %s\n", date);
  3197.     fprintf(stderr,"\n\t%s   %s, %s\n", copyright,authors[x],authors[1-x]);
  3198.     fprintf(stderr, "\n\tSend comments and requests for help to %s", help_email);
  3199.     fprintf(stderr, "\n\tSend bugs, suggestions and mods to %s\n", bug_email);
  3200. }
  3201. #endif
  3202.